[ORC][JITLink] Merge JITLink AllocActionCall and ORC WrapperFunctionCall.
These types performed identical roles. Merging them simplifies interoperability between JITLink and ORC APIs (allowing us to address a few FIXMEs).
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
#include "adt.h"
|
#include "adt.h"
|
||||||
#include "c_api.h"
|
#include "c_api.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "executor_address.h"
|
||||||
|
#include "wrapper_function_utils.h"
|
||||||
|
|
||||||
using namespace __orc_rt;
|
using namespace __orc_rt;
|
||||||
|
|
||||||
@@ -49,20 +51,24 @@ void walkEHFrameSection(span<const char> EHFrameSection,
|
|||||||
|
|
||||||
ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
|
ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
|
||||||
__orc_rt_macho_register_ehframe_section(char *ArgData, size_t ArgSize) {
|
__orc_rt_macho_register_ehframe_section(char *ArgData, size_t ArgSize) {
|
||||||
// NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
// is taken to be the range of the eh-frame section.
|
ArgData, ArgSize,
|
||||||
bool HasError = false;
|
[](ExecutorAddrRange FrameSection) -> Error {
|
||||||
walkEHFrameSection(span<const char>(ArgData, ArgSize), __register_frame);
|
walkEHFrameSection(FrameSection.toSpan<const char>(),
|
||||||
return __orc_rt_CreateCWrapperFunctionResultFromRange((char*)&HasError,
|
__register_frame);
|
||||||
sizeof(HasError));
|
return Error::success();
|
||||||
|
})
|
||||||
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
|
ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
|
||||||
__orc_rt_macho_deregister_ehframe_section(char *ArgData, size_t ArgSize) {
|
__orc_rt_macho_deregister_ehframe_section(char *ArgData, size_t ArgSize) {
|
||||||
// NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
// is taken to be the range of the eh-frame section.
|
ArgData, ArgSize,
|
||||||
bool HasError = false;
|
[](ExecutorAddrRange FrameSection) -> Error {
|
||||||
walkEHFrameSection(span<const char>(ArgData, ArgSize), __deregister_frame);
|
walkEHFrameSection(FrameSection.toSpan<const char>(),
|
||||||
return __orc_rt_CreateCWrapperFunctionResultFromRange((char*)&HasError,
|
__deregister_frame);
|
||||||
sizeof(HasError));
|
return Error::success();
|
||||||
|
})
|
||||||
|
.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,12 +595,11 @@ ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
|
|||||||
__orc_rt_macho_register_thread_data_section(char *ArgData, size_t ArgSize) {
|
__orc_rt_macho_register_thread_data_section(char *ArgData, size_t ArgSize) {
|
||||||
// NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer
|
// NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer
|
||||||
// is taken to be the range of the thread data section.
|
// is taken to be the range of the thread data section.
|
||||||
return WrapperFunction<SPSError()>::handle(
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
nullptr, 0,
|
ArgData, ArgSize,
|
||||||
[&]() {
|
[](ExecutorAddrRange R) {
|
||||||
return MachOPlatformRuntimeState::get()
|
return MachOPlatformRuntimeState::get()
|
||||||
.registerThreadDataSection(
|
.registerThreadDataSection(R.toSpan<const char>());
|
||||||
span<const char>(ArgData, ArgSize));
|
|
||||||
})
|
})
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
@@ -609,12 +608,11 @@ ORC_RT_INTERFACE __orc_rt_CWrapperFunctionResult
|
|||||||
__orc_rt_macho_deregister_thread_data_section(char *ArgData, size_t ArgSize) {
|
__orc_rt_macho_deregister_thread_data_section(char *ArgData, size_t ArgSize) {
|
||||||
// NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer
|
// NOTE: Does not use SPS to deserialize arg buffer, instead the arg buffer
|
||||||
// is taken to be the range of the thread data section.
|
// is taken to be the range of the thread data section.
|
||||||
return WrapperFunction<SPSError()>::handle(
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
nullptr, 0,
|
ArgData, ArgSize,
|
||||||
[&]() {
|
[](ExecutorAddrRange R) {
|
||||||
return MachOPlatformRuntimeState::get()
|
return MachOPlatformRuntimeState::get()
|
||||||
.deregisterThreadDataSection(
|
.deregisterThreadDataSection(R.toSpan<const char>());
|
||||||
span<const char>(ArgData, ArgSize));
|
|
||||||
})
|
})
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,20 +25,16 @@ namespace jitlink {
|
|||||||
class EHFrameRegistrar {
|
class EHFrameRegistrar {
|
||||||
public:
|
public:
|
||||||
virtual ~EHFrameRegistrar();
|
virtual ~EHFrameRegistrar();
|
||||||
virtual Error registerEHFrames(orc::ExecutorAddr EHFrameSectionAddr,
|
virtual Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
|
||||||
size_t EHFrameSectionSize) = 0;
|
virtual Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) = 0;
|
||||||
virtual Error deregisterEHFrames(orc::ExecutorAddr EHFrameSectionAddr,
|
|
||||||
size_t EHFrameSectionSize) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Registers / Deregisters EH-frames in the current process.
|
/// Registers / Deregisters EH-frames in the current process.
|
||||||
class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
|
class InProcessEHFrameRegistrar final : public EHFrameRegistrar {
|
||||||
public:
|
public:
|
||||||
Error registerEHFrames(orc::ExecutorAddr EHFrameSectionAddr,
|
Error registerEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
|
||||||
size_t EHFrameSectionSize) override;
|
|
||||||
|
|
||||||
Error deregisterEHFrames(orc::ExecutorAddr EHFrameSectionAddr,
|
Error deregisterEHFrames(orc::ExecutorAddrRange EHFrameSection) override;
|
||||||
size_t EHFrameSectionSize) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using StoreFrameRangeFunction = std::function<void(
|
using StoreFrameRangeFunction = std::function<void(
|
||||||
|
|||||||
@@ -797,6 +797,10 @@ public:
|
|||||||
}
|
}
|
||||||
orc::ExecutorAddrDiff getSize() const { return getEnd() - getStart(); }
|
orc::ExecutorAddrDiff getSize() const { return getEnd() - getStart(); }
|
||||||
|
|
||||||
|
orc::ExecutorAddrRange getRange() const {
|
||||||
|
return orc::ExecutorAddrRange(getStart(), getEnd());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Block *First = nullptr;
|
Block *First = nullptr;
|
||||||
Block *Last = nullptr;
|
Block *Last = nullptr;
|
||||||
@@ -1388,7 +1392,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// Accessing this object after finalization will result in undefined
|
/// Accessing this object after finalization will result in undefined
|
||||||
/// behavior.
|
/// behavior.
|
||||||
AllocActions &allocActions() { return AAs; }
|
orc::shared::AllocActions &allocActions() { return AAs; }
|
||||||
|
|
||||||
/// Dump the graph.
|
/// Dump the graph.
|
||||||
void dump(raw_ostream &OS);
|
void dump(raw_ostream &OS);
|
||||||
@@ -1406,7 +1410,7 @@ private:
|
|||||||
SectionList Sections;
|
SectionList Sections;
|
||||||
ExternalSymbolSet ExternalSymbols;
|
ExternalSymbolSet ExternalSymbols;
|
||||||
ExternalSymbolSet AbsoluteSymbols;
|
ExternalSymbolSet AbsoluteSymbols;
|
||||||
AllocActions AAs;
|
orc::shared::AllocActions AAs;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline MutableArrayRef<char> Block::getMutableContent(LinkGraph &G) {
|
inline MutableArrayRef<char> Block::getMutableContent(LinkGraph &G) {
|
||||||
|
|||||||
@@ -14,8 +14,10 @@
|
|||||||
#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
|
#define LLVM_EXECUTIONENGINE_JITLINK_JITLINKMEMORYMANAGER_H
|
||||||
|
|
||||||
#include "llvm/ADT/FunctionExtras.h"
|
#include "llvm/ADT/FunctionExtras.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
|
#include "llvm/ExecutionEngine/JITLink/JITLinkDylib.h"
|
||||||
#include "llvm/ExecutionEngine/JITLink/MemoryFlags.h"
|
#include "llvm/ExecutionEngine/JITLink/MemoryFlags.h"
|
||||||
|
#include "llvm/ExecutionEngine/Orc/Shared/AllocationActions.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
@@ -34,47 +36,6 @@ class Block;
|
|||||||
class LinkGraph;
|
class LinkGraph;
|
||||||
class Section;
|
class Section;
|
||||||
|
|
||||||
/// Represents a call to a graph-memory-management support function in the
|
|
||||||
/// executor.
|
|
||||||
///
|
|
||||||
/// Support functions are called as:
|
|
||||||
///
|
|
||||||
/// auto *Result =
|
|
||||||
/// ((char*(*)(const void*, size_t))FnAddr)(
|
|
||||||
/// (const void*)CtxAddr, (size_t)CtxSize)
|
|
||||||
///
|
|
||||||
/// A null result is interpreted as success.
|
|
||||||
///
|
|
||||||
/// A non-null result is interpreted as a heap-allocated string containing
|
|
||||||
/// an error message to report to the allocator (the allocator's
|
|
||||||
/// executor-side implementation code is responsible for freeing the error
|
|
||||||
/// string).
|
|
||||||
struct AllocActionCall {
|
|
||||||
orc::ExecutorAddr FnAddr;
|
|
||||||
orc::ExecutorAddr CtxAddr;
|
|
||||||
orc::ExecutorAddrDiff CtxSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A pair of AllocActionCalls, one to be run at finalization time, one to be
|
|
||||||
/// run at deallocation time.
|
|
||||||
///
|
|
||||||
/// AllocActionCallPairs should be constructed for paired operations (e.g.
|
|
||||||
/// __register_ehframe and __deregister_ehframe for eh-frame registration).
|
|
||||||
/// See comments for AllocActions for execution ordering.
|
|
||||||
///
|
|
||||||
/// For unpaired operations one or the other member can be left unused, as
|
|
||||||
/// AllocationActionCalls with an FnAddr of zero will be skipped.
|
|
||||||
struct AllocActionCallPair {
|
|
||||||
AllocActionCall Finalize;
|
|
||||||
AllocActionCall Dealloc;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A vector of allocation actions to be run for this allocation.
|
|
||||||
///
|
|
||||||
/// Finalize allocations will be run in order at finalize time. Dealloc
|
|
||||||
/// actions will be run in reverse order at deallocation time.
|
|
||||||
using AllocActions = std::vector<AllocActionCallPair>;
|
|
||||||
|
|
||||||
/// Manages allocations of JIT memory.
|
/// Manages allocations of JIT memory.
|
||||||
///
|
///
|
||||||
/// Instances of this class may be accessed concurrently from multiple threads
|
/// Instances of this class may be accessed concurrently from multiple threads
|
||||||
@@ -315,7 +276,7 @@ public:
|
|||||||
/// Returns a reference to the AllocActions in the graph.
|
/// Returns a reference to the AllocActions in the graph.
|
||||||
/// This convenience function saves callers from having to #include
|
/// This convenience function saves callers from having to #include
|
||||||
/// LinkGraph.h if all they need are allocation actions.
|
/// LinkGraph.h if all they need are allocation actions.
|
||||||
AllocActions &graphAllocActions();
|
orc::shared::AllocActions &graphAllocActions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LinkGraph &G;
|
LinkGraph &G;
|
||||||
@@ -416,12 +377,12 @@ private:
|
|||||||
// There shouldn't need to be a heap alloc for this.
|
// There shouldn't need to be a heap alloc for this.
|
||||||
struct FinalizedAllocInfo {
|
struct FinalizedAllocInfo {
|
||||||
sys::MemoryBlock StandardSegments;
|
sys::MemoryBlock StandardSegments;
|
||||||
std::vector<AllocActionCall> DeallocActions;
|
std::vector<orc::shared::WrapperFunctionCall> DeallocActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
FinalizedAlloc
|
FinalizedAlloc createFinalizedAlloc(
|
||||||
createFinalizedAlloc(sys::MemoryBlock StandardSegments,
|
sys::MemoryBlock StandardSegments,
|
||||||
std::vector<AllocActionCall> DeallocActions);
|
std::vector<orc::shared::WrapperFunctionCall> DeallocActions);
|
||||||
|
|
||||||
uint64_t PageSize;
|
uint64_t PageSize;
|
||||||
std::mutex FinalizedAllocsMutex;
|
std::mutex FinalizedAllocsMutex;
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ public:
|
|||||||
: ES(ES), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
|
: ES(ES), RegisterEHFrameWrapperFnAddr(RegisterEHFrameWrapperFnAddr),
|
||||||
DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
|
DeregisterEHFrameWrapperFnAddr(DeregisterEHFRameWrapperFnAddr) {}
|
||||||
|
|
||||||
Error registerEHFrames(ExecutorAddr EHFrameSectionAddr,
|
Error registerEHFrames(ExecutorAddrRange EHFrameSection) override;
|
||||||
size_t EHFrameSectionSize) override;
|
Error deregisterEHFrames(ExecutorAddrRange EHFrameSection) override;
|
||||||
Error deregisterEHFrames(ExecutorAddr EHFrameSectionAddr,
|
|
||||||
size_t EHFrameSectionSize) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExecutionSession &ES;
|
ExecutionSession &ES;
|
||||||
|
|||||||
@@ -89,11 +89,6 @@ private:
|
|||||||
ExecutorAddr RemoteAddr;
|
ExecutorAddr RemoteAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EHFrame {
|
|
||||||
ExecutorAddr Addr;
|
|
||||||
uint64_t Size;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Group of section allocations to be allocated together in the executor. The
|
// Group of section allocations to be allocated together in the executor. The
|
||||||
// RemoteCodeAddr will stand in as the id of the group for deallocation
|
// RemoteCodeAddr will stand in as the id of the group for deallocation
|
||||||
// purposes.
|
// purposes.
|
||||||
@@ -107,7 +102,7 @@ private:
|
|||||||
ExecutorAddrRange RemoteCode;
|
ExecutorAddrRange RemoteCode;
|
||||||
ExecutorAddrRange RemoteROData;
|
ExecutorAddrRange RemoteROData;
|
||||||
ExecutorAddrRange RemoteRWData;
|
ExecutorAddrRange RemoteRWData;
|
||||||
std::vector<EHFrame> UnfinalizedEHFrames;
|
std::vector<ExecutorAddrRange> UnfinalizedEHFrames;
|
||||||
std::vector<Alloc> CodeAllocs, RODataAllocs, RWDataAllocs;
|
std::vector<Alloc> CodeAllocs, RODataAllocs, RWDataAllocs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -216,17 +216,11 @@ public:
|
|||||||
ResourceKey SrcKey) override;
|
ResourceKey SrcKey) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct EHFrameRange {
|
|
||||||
orc::ExecutorAddr Addr;
|
|
||||||
size_t Size;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::mutex EHFramePluginMutex;
|
std::mutex EHFramePluginMutex;
|
||||||
ExecutionSession &ES;
|
ExecutionSession &ES;
|
||||||
std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
|
std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
|
||||||
DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
|
DenseMap<MaterializationResponsibility *, ExecutorAddrRange> InProcessLinks;
|
||||||
DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
|
DenseMap<ResourceKey, std::vector<ExecutorAddrRange>> EHFrameRanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace orc
|
} // end namespace orc
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ extern const char *MemoryWriteUInt32sWrapperName;
|
|||||||
extern const char *MemoryWriteUInt64sWrapperName;
|
extern const char *MemoryWriteUInt64sWrapperName;
|
||||||
extern const char *MemoryWriteBuffersWrapperName;
|
extern const char *MemoryWriteBuffersWrapperName;
|
||||||
|
|
||||||
extern const char *RegisterEHFrameSectionCustomDirectWrapperName;
|
extern const char *RegisterEHFrameSectionWrapperName;
|
||||||
extern const char *DeregisterEHFrameSectionCustomDirectWrapperName;
|
extern const char *DeregisterEHFrameSectionWrapperName;
|
||||||
|
|
||||||
extern const char *RunAsMainWrapperName;
|
extern const char *RunAsMainWrapperName;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
|
#define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
|
||||||
|
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
@@ -112,12 +113,22 @@ public:
|
|||||||
|
|
||||||
static bool serialize(SPSOutputBuffer &OB) { return true; }
|
static bool serialize(SPSOutputBuffer &OB) { return true; }
|
||||||
static bool deserialize(SPSInputBuffer &IB) { return true; }
|
static bool deserialize(SPSInputBuffer &IB) { return true; }
|
||||||
|
|
||||||
|
static bool serializeToSmallVector(SmallVectorImpl<char> &V) { return true; }
|
||||||
|
|
||||||
|
static bool deserializeFromSmallVector(const SmallVectorImpl<char> &V) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Non-empty list specialization for SPSArgList.
|
// Non-empty list specialization for SPSArgList.
|
||||||
template <typename SPSTagT, typename... SPSTagTs>
|
template <typename SPSTagT, typename... SPSTagTs>
|
||||||
class SPSArgList<SPSTagT, SPSTagTs...> {
|
class SPSArgList<SPSTagT, SPSTagTs...> {
|
||||||
public:
|
public:
|
||||||
|
// FIXME: This typedef is here to enable SPS arg serialization from
|
||||||
|
// JITLink. It can be removed once JITLink can access SPS directly.
|
||||||
|
using OutputBuffer = SPSOutputBuffer;
|
||||||
|
|
||||||
template <typename ArgT, typename... ArgTs>
|
template <typename ArgT, typename... ArgTs>
|
||||||
static size_t size(const ArgT &Arg, const ArgTs &...Args) {
|
static size_t size(const ArgT &Arg, const ArgTs &...Args) {
|
||||||
return SPSSerializationTraits<SPSTagT, ArgT>::size(Arg) +
|
return SPSSerializationTraits<SPSTagT, ArgT>::size(Arg) +
|
||||||
@@ -284,6 +295,40 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Trivial SmallVectorImpl<T> -> SPSSequence<char> serialization.
|
||||||
|
template <typename SPSElementTagT, typename T>
|
||||||
|
class TrivialSPSSequenceSerialization<SPSElementTagT, SmallVectorImpl<T>> {
|
||||||
|
public:
|
||||||
|
static constexpr bool available = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Trivial SPSSequence<SPSElementTagT> -> SmallVectorImpl<T> deserialization.
|
||||||
|
template <typename SPSElementTagT, typename T>
|
||||||
|
class TrivialSPSSequenceDeserialization<SPSElementTagT, SmallVectorImpl<T>> {
|
||||||
|
public:
|
||||||
|
static constexpr bool available = true;
|
||||||
|
|
||||||
|
using element_type = typename SmallVectorImpl<T>::value_type;
|
||||||
|
|
||||||
|
static void reserve(SmallVectorImpl<T> &V, uint64_t Size) { V.reserve(Size); }
|
||||||
|
static bool append(SmallVectorImpl<T> &V, T E) {
|
||||||
|
V.push_back(std::move(E));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Trivial SmallVectorImpl<T> -> SPSSequence<char> serialization.
|
||||||
|
template <typename SPSElementTagT, typename T, unsigned N>
|
||||||
|
class TrivialSPSSequenceSerialization<SPSElementTagT, SmallVector<T, N>>
|
||||||
|
: public TrivialSPSSequenceSerialization<SPSElementTagT,
|
||||||
|
SmallVectorImpl<T>> {};
|
||||||
|
|
||||||
|
/// Trivial SPSSequence<SPSElementTagT> -> SmallVectorImpl<T> deserialization.
|
||||||
|
template <typename SPSElementTagT, typename T, unsigned N>
|
||||||
|
class TrivialSPSSequenceDeserialization<SPSElementTagT, SmallVector<T, N>>
|
||||||
|
: public TrivialSPSSequenceDeserialization<SPSElementTagT,
|
||||||
|
SmallVectorImpl<T>> {};
|
||||||
|
|
||||||
/// Trivial ArrayRef<T> -> SPSSequence<SPSElementTagT> serialization.
|
/// Trivial ArrayRef<T> -> SPSSequence<SPSElementTagT> serialization.
|
||||||
template <typename SPSElementTagT, typename T>
|
template <typename SPSElementTagT, typename T>
|
||||||
class TrivialSPSSequenceSerialization<SPSElementTagT, ArrayRef<T>> {
|
class TrivialSPSSequenceSerialization<SPSElementTagT, ArrayRef<T>> {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||||
|
#include "llvm/ExecutionEngine/Orc/Shared/AllocationActions.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
|
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
|
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
|
||||||
@@ -69,50 +70,6 @@ inline std::string getWireProtectionFlagsStr(WireProtectionFlags WPF) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WrapperFunctionCall {
|
|
||||||
ExecutorAddr Func;
|
|
||||||
ExecutorAddrRange ArgData;
|
|
||||||
|
|
||||||
WrapperFunctionCall() = default;
|
|
||||||
WrapperFunctionCall(ExecutorAddr Func, ExecutorAddr ArgData,
|
|
||||||
ExecutorAddrDiff ArgSize)
|
|
||||||
: Func(Func), ArgData(ArgData, ArgSize) {}
|
|
||||||
WrapperFunctionCall(ExecutorAddr Func, ExecutorAddrRange ArgData)
|
|
||||||
: Func(Func), ArgData(ArgData) {}
|
|
||||||
|
|
||||||
shared::WrapperFunctionResult run() {
|
|
||||||
using FnTy =
|
|
||||||
shared::CWrapperFunctionResult(const char *ArgData, size_t ArgSize);
|
|
||||||
return shared::WrapperFunctionResult(
|
|
||||||
Func.toPtr<FnTy *>()(ArgData.Start.toPtr<const char *>(),
|
|
||||||
static_cast<size_t>(ArgData.size())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run call and deserialize result using SPS.
|
|
||||||
template <typename SPSRetT, typename RetT> Error runWithSPSRet(RetT &RetVal) {
|
|
||||||
auto WFR = run();
|
|
||||||
if (const char *ErrMsg = WFR.getOutOfBandError())
|
|
||||||
return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
|
|
||||||
shared::SPSInputBuffer IB(WFR.data(), WFR.size());
|
|
||||||
if (!shared::SPSSerializationTraits<SPSRetT, RetT>::deserialize(IB, RetVal))
|
|
||||||
return make_error<StringError>("Could not deserialize result from "
|
|
||||||
"serialized wrapper function call",
|
|
||||||
inconvertibleErrorCode());
|
|
||||||
return Error::success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Overload for SPS functions returning void.
|
|
||||||
Error runWithSPSRet() {
|
|
||||||
shared::SPSEmpty E;
|
|
||||||
return runWithSPSRet<shared::SPSEmpty>(E);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AllocationActionsPair {
|
|
||||||
WrapperFunctionCall Finalize;
|
|
||||||
WrapperFunctionCall Deallocate;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SegFinalizeRequest {
|
struct SegFinalizeRequest {
|
||||||
WireProtectionFlags Prot;
|
WireProtectionFlags Prot;
|
||||||
ExecutorAddr Addr;
|
ExecutorAddr Addr;
|
||||||
@@ -122,7 +79,7 @@ struct SegFinalizeRequest {
|
|||||||
|
|
||||||
struct FinalizeRequest {
|
struct FinalizeRequest {
|
||||||
std::vector<SegFinalizeRequest> Segments;
|
std::vector<SegFinalizeRequest> Segments;
|
||||||
std::vector<AllocationActionsPair> Actions;
|
shared::AllocActions Actions;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct UIntWrite {
|
template <typename T> struct UIntWrite {
|
||||||
@@ -167,17 +124,12 @@ namespace shared {
|
|||||||
|
|
||||||
class SPSMemoryProtectionFlags {};
|
class SPSMemoryProtectionFlags {};
|
||||||
|
|
||||||
using SPSWrapperFunctionCall = SPSTuple<SPSExecutorAddr, SPSExecutorAddrRange>;
|
|
||||||
|
|
||||||
using SPSSegFinalizeRequest =
|
using SPSSegFinalizeRequest =
|
||||||
SPSTuple<SPSMemoryProtectionFlags, SPSExecutorAddr, uint64_t,
|
SPSTuple<SPSMemoryProtectionFlags, SPSExecutorAddr, uint64_t,
|
||||||
SPSSequence<char>>;
|
SPSSequence<char>>;
|
||||||
|
|
||||||
using SPSAllocationActionsPair =
|
|
||||||
SPSTuple<SPSWrapperFunctionCall, SPSWrapperFunctionCall>;
|
|
||||||
|
|
||||||
using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>,
|
using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>,
|
||||||
SPSSequence<SPSAllocationActionsPair>>;
|
SPSSequence<SPSAllocActionCallPair>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>;
|
using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>;
|
||||||
@@ -212,48 +164,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
|
||||||
class SPSSerializationTraits<SPSWrapperFunctionCall,
|
|
||||||
tpctypes::WrapperFunctionCall> {
|
|
||||||
using AL = SPSWrapperFunctionCall::AsArgList;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static size_t size(const tpctypes::WrapperFunctionCall &WFC) {
|
|
||||||
return AL::size(WFC.Func, WFC.ArgData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool serialize(SPSOutputBuffer &OB,
|
|
||||||
const tpctypes::WrapperFunctionCall &WFC) {
|
|
||||||
return AL::serialize(OB, WFC.Func, WFC.ArgData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool deserialize(SPSInputBuffer &IB,
|
|
||||||
tpctypes::WrapperFunctionCall &WFC) {
|
|
||||||
return AL::deserialize(IB, WFC.Func, WFC.ArgData);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class SPSSerializationTraits<SPSAllocationActionsPair,
|
|
||||||
tpctypes::AllocationActionsPair> {
|
|
||||||
using AL = SPSAllocationActionsPair::AsArgList;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static size_t size(const tpctypes::AllocationActionsPair &AAP) {
|
|
||||||
return AL::size(AAP.Finalize, AAP.Deallocate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool serialize(SPSOutputBuffer &OB,
|
|
||||||
const tpctypes::AllocationActionsPair &AAP) {
|
|
||||||
return AL::serialize(OB, AAP.Finalize, AAP.Deallocate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool deserialize(SPSInputBuffer &IB,
|
|
||||||
tpctypes::AllocationActionsPair &AAP) {
|
|
||||||
return AL::deserialize(IB, AAP.Finalize, AAP.Deallocate);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class SPSSerializationTraits<SPSSegFinalizeRequest,
|
class SPSSerializationTraits<SPSSegFinalizeRequest,
|
||||||
tpctypes::SegFinalizeRequest> {
|
tpctypes::SegFinalizeRequest> {
|
||||||
|
|||||||
@@ -356,6 +356,15 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename SPSRetTagT>
|
||||||
|
class ResultSerializer<SPSRetTagT, ErrorSuccess> {
|
||||||
|
public:
|
||||||
|
static WrapperFunctionResult serialize(ErrorSuccess Err) {
|
||||||
|
return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
|
||||||
|
toSPSSerializable(std::move(Err)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename SPSRetTagT, typename T>
|
template <typename SPSRetTagT, typename T>
|
||||||
class ResultSerializer<SPSRetTagT, Expected<T>> {
|
class ResultSerializer<SPSRetTagT, Expected<T>> {
|
||||||
public:
|
public:
|
||||||
@@ -609,6 +618,116 @@ makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) {
|
|||||||
return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
|
return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a serialized wrapper function call.
|
||||||
|
/// Serializing calls themselves allows us to batch them: We can make one
|
||||||
|
/// "run-wrapper-functions" utility and send it a list of calls to run.
|
||||||
|
///
|
||||||
|
/// The motivating use-case for this API is JITLink allocation actions, where
|
||||||
|
/// we want to run multiple functions to finalize linked memory without having
|
||||||
|
/// to make separate IPC calls for each one.
|
||||||
|
class WrapperFunctionCall {
|
||||||
|
public:
|
||||||
|
using ArgDataBufferType = SmallVector<char, 24>;
|
||||||
|
|
||||||
|
/// Create a WrapperFunctionCall using the given SPS serializer to serialize
|
||||||
|
/// the arguments.
|
||||||
|
template <typename SPSSerializer, typename... ArgTs>
|
||||||
|
static Expected<WrapperFunctionCall> Create(ExecutorAddr FnAddr,
|
||||||
|
const ArgTs &...Args) {
|
||||||
|
ArgDataBufferType ArgData;
|
||||||
|
ArgData.resize(SPSSerializer::size(Args...));
|
||||||
|
SPSOutputBuffer OB(&ArgData[0], ArgData.size());
|
||||||
|
if (SPSSerializer::serialize(OB, Args...))
|
||||||
|
return WrapperFunctionCall(FnAddr, std::move(ArgData));
|
||||||
|
return make_error<StringError>("Cannot serialize arguments for "
|
||||||
|
"AllocActionCall",
|
||||||
|
inconvertibleErrorCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
WrapperFunctionCall() = default;
|
||||||
|
|
||||||
|
/// Create a WrapperFunctionCall from a target function and arg buffer.
|
||||||
|
WrapperFunctionCall(ExecutorAddr FnAddr, ArgDataBufferType ArgData)
|
||||||
|
: FnAddr(FnAddr), ArgData(std::move(ArgData)) {}
|
||||||
|
|
||||||
|
/// Returns the address to be called.
|
||||||
|
const ExecutorAddr &getCallee() const { return FnAddr; }
|
||||||
|
|
||||||
|
/// Returns the argument data.
|
||||||
|
const ArgDataBufferType &getArgData() const { return ArgData; }
|
||||||
|
|
||||||
|
/// WrapperFunctionCalls convert to true if the callee is non-null.
|
||||||
|
explicit operator bool() const { return !!FnAddr; }
|
||||||
|
|
||||||
|
/// Run call returning raw WrapperFunctionResult.
|
||||||
|
shared::WrapperFunctionResult run() {
|
||||||
|
using FnTy =
|
||||||
|
shared::CWrapperFunctionResult(const char *ArgData, size_t ArgSize);
|
||||||
|
return shared::WrapperFunctionResult(
|
||||||
|
FnAddr.toPtr<FnTy *>()(ArgData.data(), ArgData.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run call and deserialize result using SPS.
|
||||||
|
template <typename SPSRetT, typename RetT>
|
||||||
|
std::enable_if_t<!std::is_same<SPSRetT, void>::value, Error>
|
||||||
|
runWithSPSRet(RetT &RetVal) {
|
||||||
|
auto WFR = run();
|
||||||
|
if (const char *ErrMsg = WFR.getOutOfBandError())
|
||||||
|
return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
|
||||||
|
shared::SPSInputBuffer IB(WFR.data(), WFR.size());
|
||||||
|
if (!shared::SPSSerializationTraits<SPSRetT, RetT>::deserialize(IB, RetVal))
|
||||||
|
return make_error<StringError>("Could not deserialize result from "
|
||||||
|
"serialized wrapper function call",
|
||||||
|
inconvertibleErrorCode());
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Overload for SPS functions returning void.
|
||||||
|
template <typename SPSRetT>
|
||||||
|
std::enable_if_t<std::is_same<SPSRetT, void>::value, Error> runWithSPSRet() {
|
||||||
|
shared::SPSEmpty E;
|
||||||
|
return runWithSPSRet<shared::SPSEmpty>(E);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run call and deserialize an SPSError result. SPSError returns and
|
||||||
|
/// deserialization failures are merged into the returned error.
|
||||||
|
Error runWithSPSRetErrorMerged() {
|
||||||
|
detail::SPSSerializableError RetErr;
|
||||||
|
if (auto Err = runWithSPSRet<SPSError>(RetErr))
|
||||||
|
return Err;
|
||||||
|
return detail::fromSPSSerializable(std::move(RetErr));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
orc::ExecutorAddr FnAddr;
|
||||||
|
ArgDataBufferType ArgData;
|
||||||
|
};
|
||||||
|
|
||||||
|
using SPSWrapperFunctionCall = SPSTuple<SPSExecutorAddr, SPSSequence<char>>;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class SPSSerializationTraits<SPSWrapperFunctionCall, WrapperFunctionCall> {
|
||||||
|
public:
|
||||||
|
static size_t size(const WrapperFunctionCall &WFC) {
|
||||||
|
return SPSWrapperFunctionCall::AsArgList::size(WFC.getCallee(),
|
||||||
|
WFC.getArgData());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool serialize(SPSOutputBuffer &OB, const WrapperFunctionCall &WFC) {
|
||||||
|
return SPSWrapperFunctionCall::AsArgList::serialize(OB, WFC.getCallee(),
|
||||||
|
WFC.getArgData());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool deserialize(SPSInputBuffer &IB, WrapperFunctionCall &WFC) {
|
||||||
|
ExecutorAddr FnAddr;
|
||||||
|
WrapperFunctionCall::ArgDataBufferType ArgData;
|
||||||
|
if (!SPSWrapperFunctionCall::AsArgList::deserialize(IB, FnAddr, ArgData))
|
||||||
|
return false;
|
||||||
|
WFC = WrapperFunctionCall(FnAddr, std::move(ArgData));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace shared
|
} // end namespace shared
|
||||||
} // end namespace orc
|
} // end namespace orc
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|||||||
@@ -33,22 +33,6 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
|
|||||||
} // end namespace orc
|
} // end namespace orc
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
/// An eh-frame registration utility suitable for use as a support function
|
|
||||||
/// call. This function expects the direct address and size of the eh-frame
|
|
||||||
/// section to register as its arguments (it does not treat its arguments as
|
|
||||||
/// pointers to an SPS-serialized arg buffer).
|
|
||||||
extern "C" llvm::orc::shared::CWrapperFunctionResult
|
|
||||||
llvm_orc_registerEHFrameSectionCustomDirectWrapper(
|
|
||||||
const char *EHFrameSectionAddr, uint64_t Size);
|
|
||||||
|
|
||||||
/// An eh-frame deregistration utility suitable for use as a support function
|
|
||||||
/// call. This function expects the direct address and size of the eh-frame
|
|
||||||
/// section to register as its arguments (it does not treat its arguments as
|
|
||||||
/// pointers to an SPS-serialized arg buffer).
|
|
||||||
extern "C" llvm::orc::shared::CWrapperFunctionResult
|
|
||||||
llvm_orc_deregisterEHFrameSectionCustomDirectWrapper(
|
|
||||||
const char *EHFrameSectionAddr, uint64_t Size);
|
|
||||||
|
|
||||||
extern "C" llvm::orc::shared::CWrapperFunctionResult
|
extern "C" llvm::orc::shared::CWrapperFunctionResult
|
||||||
llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size);
|
llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size);
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct Allocation {
|
struct Allocation {
|
||||||
size_t Size = 0;
|
size_t Size = 0;
|
||||||
std::vector<tpctypes::WrapperFunctionCall> DeallocationActions;
|
std::vector<shared::WrapperFunctionCall> DeallocationActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
using AllocationsMap = DenseMap<void *, Allocation>;
|
using AllocationsMap = DenseMap<void *, Allocation>;
|
||||||
|
|||||||
@@ -759,15 +759,15 @@ Error EHFrameNullTerminator::operator()(LinkGraph &G) {
|
|||||||
EHFrameRegistrar::~EHFrameRegistrar() {}
|
EHFrameRegistrar::~EHFrameRegistrar() {}
|
||||||
|
|
||||||
Error InProcessEHFrameRegistrar::registerEHFrames(
|
Error InProcessEHFrameRegistrar::registerEHFrames(
|
||||||
orc::ExecutorAddr EHFrameSectionAddr, size_t EHFrameSectionSize) {
|
orc::ExecutorAddrRange EHFrameSection) {
|
||||||
return orc::registerEHFrameSection(EHFrameSectionAddr.toPtr<void *>(),
|
return orc::registerEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
|
||||||
EHFrameSectionSize);
|
EHFrameSection.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Error InProcessEHFrameRegistrar::deregisterEHFrames(
|
Error InProcessEHFrameRegistrar::deregisterEHFrames(
|
||||||
orc::ExecutorAddr EHFrameSectionAddr, size_t EHFrameSectionSize) {
|
orc::ExecutorAddrRange EHFrameSection) {
|
||||||
return orc::deregisterEHFrameSection(EHFrameSectionAddr.toPtr<void *>(),
|
return orc::deregisterEHFrameSection(EHFrameSection.Start.toPtr<void *>(),
|
||||||
EHFrameSectionSize);
|
EHFrameSection.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkGraphPassFunction
|
LinkGraphPassFunction
|
||||||
|
|||||||
@@ -15,63 +15,12 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// FIXME: Remove this copy of CWrapperFunctionResult as soon as JITLink can
|
|
||||||
// depend on shared utils from Orc.
|
|
||||||
|
|
||||||
// Must be kept in-sync with compiler-rt/lib/orc/c-api.h.
|
|
||||||
union CWrapperFunctionResultDataUnion {
|
|
||||||
char *ValuePtr;
|
|
||||||
char Value[sizeof(ValuePtr)];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Must be kept in-sync with compiler-rt/lib/orc/c-api.h.
|
|
||||||
typedef struct {
|
|
||||||
CWrapperFunctionResultDataUnion Data;
|
|
||||||
size_t Size;
|
|
||||||
} CWrapperFunctionResult;
|
|
||||||
|
|
||||||
Error toError(CWrapperFunctionResult R) {
|
|
||||||
bool HasError = false;
|
|
||||||
std::string ErrMsg;
|
|
||||||
if (R.Size) {
|
|
||||||
bool Large = R.Size > sizeof(CWrapperFunctionResultDataUnion);
|
|
||||||
char *Content = Large ? R.Data.ValuePtr : R.Data.Value;
|
|
||||||
if (Content[0]) {
|
|
||||||
HasError = true;
|
|
||||||
constexpr unsigned StrStart = 1 + sizeof(uint64_t);
|
|
||||||
ErrMsg.resize(R.Size - StrStart);
|
|
||||||
memcpy(&ErrMsg[0], Content + StrStart, R.Size - StrStart);
|
|
||||||
}
|
|
||||||
if (Large)
|
|
||||||
free(R.Data.ValuePtr);
|
|
||||||
} else if (R.Data.ValuePtr) {
|
|
||||||
HasError = true;
|
|
||||||
ErrMsg = R.Data.ValuePtr;
|
|
||||||
free(R.Data.ValuePtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasError)
|
|
||||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
|
||||||
return Error::success();
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace jitlink {
|
namespace jitlink {
|
||||||
|
|
||||||
JITLinkMemoryManager::~JITLinkMemoryManager() = default;
|
JITLinkMemoryManager::~JITLinkMemoryManager() = default;
|
||||||
JITLinkMemoryManager::InFlightAlloc::~InFlightAlloc() = default;
|
JITLinkMemoryManager::InFlightAlloc::~InFlightAlloc() = default;
|
||||||
|
|
||||||
static Error runAllocAction(AllocActionCall &C) {
|
|
||||||
using WrapperFnTy = CWrapperFunctionResult (*)(const void *, size_t);
|
|
||||||
auto *Fn = C.FnAddr.toPtr<WrapperFnTy>();
|
|
||||||
|
|
||||||
return toError(
|
|
||||||
Fn(C.CtxAddr.toPtr<const void *>(), static_cast<size_t>(C.CtxSize)));
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicLayout::BasicLayout(LinkGraph &G) : G(G) {
|
BasicLayout::BasicLayout(LinkGraph &G) : G(G) {
|
||||||
|
|
||||||
for (auto &Sec : G.sections()) {
|
for (auto &Sec : G.sections()) {
|
||||||
@@ -189,7 +138,9 @@ Error BasicLayout::apply() {
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocActions &BasicLayout::graphAllocActions() { return G.allocActions(); }
|
orc::shared::AllocActions &BasicLayout::graphAllocActions() {
|
||||||
|
return G.allocActions();
|
||||||
|
}
|
||||||
|
|
||||||
void SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
|
void SimpleSegmentAlloc::Create(JITLinkMemoryManager &MemMgr,
|
||||||
const JITLinkDylib *JD, SegmentMap Segments,
|
const JITLinkDylib *JD, SegmentMap Segments,
|
||||||
@@ -297,15 +248,15 @@ public:
|
|||||||
|
|
||||||
// Run finalization actions.
|
// Run finalization actions.
|
||||||
// FIXME: Roll back previous successful actions on failure.
|
// FIXME: Roll back previous successful actions on failure.
|
||||||
std::vector<AllocActionCall> DeallocActions;
|
std::vector<orc::shared::WrapperFunctionCall> DeallocActions;
|
||||||
DeallocActions.reserve(G.allocActions().size());
|
DeallocActions.reserve(G.allocActions().size());
|
||||||
for (auto &ActPair : G.allocActions()) {
|
for (auto &ActPair : G.allocActions()) {
|
||||||
if (ActPair.Finalize.FnAddr)
|
if (ActPair.Finalize)
|
||||||
if (auto Err = runAllocAction(ActPair.Finalize)) {
|
if (auto Err = ActPair.Finalize.runWithSPSRetErrorMerged()) {
|
||||||
OnFinalized(std::move(Err));
|
OnFinalized(std::move(Err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ActPair.Dealloc.FnAddr)
|
if (ActPair.Dealloc)
|
||||||
DeallocActions.push_back(ActPair.Dealloc);
|
DeallocActions.push_back(ActPair.Dealloc);
|
||||||
}
|
}
|
||||||
G.allocActions().clear();
|
G.allocActions().clear();
|
||||||
@@ -474,7 +425,7 @@ void InProcessMemoryManager::allocate(const JITLinkDylib *JD, LinkGraph &G,
|
|||||||
void InProcessMemoryManager::deallocate(std::vector<FinalizedAlloc> Allocs,
|
void InProcessMemoryManager::deallocate(std::vector<FinalizedAlloc> Allocs,
|
||||||
OnDeallocatedFunction OnDeallocated) {
|
OnDeallocatedFunction OnDeallocated) {
|
||||||
std::vector<sys::MemoryBlock> StandardSegmentsList;
|
std::vector<sys::MemoryBlock> StandardSegmentsList;
|
||||||
std::vector<std::vector<AllocActionCall>> DeallocActionsList;
|
std::vector<std::vector<orc::shared::WrapperFunctionCall>> DeallocActionsList;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> Lock(FinalizedAllocsMutex);
|
std::lock_guard<std::mutex> Lock(FinalizedAllocsMutex);
|
||||||
@@ -496,7 +447,7 @@ void InProcessMemoryManager::deallocate(std::vector<FinalizedAlloc> Allocs,
|
|||||||
|
|
||||||
/// Run any deallocate calls.
|
/// Run any deallocate calls.
|
||||||
while (!DeallocActions.empty()) {
|
while (!DeallocActions.empty()) {
|
||||||
if (auto Err = runAllocAction(DeallocActions.back()))
|
if (auto Err = DeallocActions.back().runWithSPSRetErrorMerged())
|
||||||
DeallocErr = joinErrors(std::move(DeallocErr), std::move(Err));
|
DeallocErr = joinErrors(std::move(DeallocErr), std::move(Err));
|
||||||
DeallocActions.pop_back();
|
DeallocActions.pop_back();
|
||||||
}
|
}
|
||||||
@@ -515,7 +466,7 @@ void InProcessMemoryManager::deallocate(std::vector<FinalizedAlloc> Allocs,
|
|||||||
JITLinkMemoryManager::FinalizedAlloc
|
JITLinkMemoryManager::FinalizedAlloc
|
||||||
InProcessMemoryManager::createFinalizedAlloc(
|
InProcessMemoryManager::createFinalizedAlloc(
|
||||||
sys::MemoryBlock StandardSegments,
|
sys::MemoryBlock StandardSegments,
|
||||||
std::vector<AllocActionCall> DeallocActions) {
|
std::vector<orc::shared::WrapperFunctionCall> DeallocActions) {
|
||||||
std::lock_guard<std::mutex> Lock(FinalizedAllocsMutex);
|
std::lock_guard<std::mutex> Lock(FinalizedAllocsMutex);
|
||||||
auto *FA = FinalizedAllocInfos.Allocate<FinalizedAllocInfo>();
|
auto *FA = FinalizedAllocInfos.Allocate<FinalizedAllocInfo>();
|
||||||
new (FA) FinalizedAllocInfo(
|
new (FA) FinalizedAllocInfo(
|
||||||
|
|||||||
@@ -349,8 +349,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
SectionRange R(MachOContainerBlock->getSection());
|
SectionRange R(MachOContainerBlock->getSection());
|
||||||
G.allocActions().push_back(
|
G.allocActions().push_back({cantFail(shared::WrapperFunctionCall::Create<
|
||||||
{{RegisterActionAddr, R.getStart(), R.getSize()}, {}});
|
SPSArgList<SPSExecutorAddrRange>>(
|
||||||
|
RegisterActionAddr, R.getRange())),
|
||||||
|
{}});
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,18 +56,15 @@ EPCEHFrameRegistrar::Create(ExecutionSession &ES) {
|
|||||||
ExecutorAddr(DeregisterEHFrameWrapperFnAddr));
|
ExecutorAddr(DeregisterEHFrameWrapperFnAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EPCEHFrameRegistrar::registerEHFrames(ExecutorAddr EHFrameSectionAddr,
|
Error EPCEHFrameRegistrar::registerEHFrames(ExecutorAddrRange EHFrameSection) {
|
||||||
size_t EHFrameSectionSize) {
|
return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(
|
||||||
return ES.callSPSWrapper<void(SPSExecutorAddr, uint64_t)>(
|
RegisterEHFrameWrapperFnAddr, EHFrameSection);
|
||||||
RegisterEHFrameWrapperFnAddr, EHFrameSectionAddr,
|
|
||||||
static_cast<uint64_t>(EHFrameSectionSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EPCEHFrameRegistrar::deregisterEHFrames(ExecutorAddr EHFrameSectionAddr,
|
Error EPCEHFrameRegistrar::deregisterEHFrames(
|
||||||
size_t EHFrameSectionSize) {
|
ExecutorAddrRange EHFrameSection) {
|
||||||
return ES.callSPSWrapper<void(SPSExecutorAddr, uint64_t)>(
|
return ES.callSPSWrapper<void(SPSExecutorAddrRange)>(
|
||||||
DeregisterEHFrameWrapperFnAddr, EHFrameSectionAddr,
|
DeregisterEHFrameWrapperFnAddr, EHFrameSection);
|
||||||
static_cast<uint64_t>(EHFrameSectionSize));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace orc
|
} // end namespace orc
|
||||||
|
|||||||
@@ -56,17 +56,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transfer allocation actions.
|
// Transfer allocation actions.
|
||||||
// FIXME: Merge JITLink and ORC SupportFunctionCall and Action list types,
|
std::swap(FR.Actions, G.allocActions());
|
||||||
// turn this into a std::swap.
|
|
||||||
FR.Actions.reserve(G.allocActions().size());
|
|
||||||
for (auto &ActPair : G.allocActions())
|
|
||||||
FR.Actions.push_back({{ExecutorAddr(ActPair.Finalize.FnAddr),
|
|
||||||
{ExecutorAddr(ActPair.Finalize.CtxAddr),
|
|
||||||
ExecutorAddrDiff(ActPair.Finalize.CtxSize)}},
|
|
||||||
{ExecutorAddr(ActPair.Dealloc.FnAddr),
|
|
||||||
{ExecutorAddr(ActPair.Dealloc.CtxAddr),
|
|
||||||
ExecutorAddrDiff(ActPair.Dealloc.CtxSize)}}});
|
|
||||||
G.allocActions().clear();
|
|
||||||
|
|
||||||
Parent.EPC.callSPSWrapperAsync<
|
Parent.EPC.callSPSWrapperAsync<
|
||||||
rt::SPSSimpleExecutorMemoryManagerFinalizeSignature>(
|
rt::SPSSimpleExecutorMemoryManagerFinalizeSignature>(
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "orc"
|
#define DEBUG_TYPE "orc"
|
||||||
|
|
||||||
|
using namespace llvm::orc::shared;
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace orc {
|
namespace orc {
|
||||||
|
|
||||||
@@ -27,10 +29,8 @@ EPCGenericRTDyldMemoryManager::CreateWithDefaultBootstrapSymbols(
|
|||||||
{SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
|
{SAs.Finalize, rt::SimpleExecutorMemoryManagerFinalizeWrapperName},
|
||||||
{SAs.Deallocate,
|
{SAs.Deallocate,
|
||||||
rt::SimpleExecutorMemoryManagerDeallocateWrapperName},
|
rt::SimpleExecutorMemoryManagerDeallocateWrapperName},
|
||||||
{SAs.RegisterEHFrame,
|
{SAs.RegisterEHFrame, rt::RegisterEHFrameSectionWrapperName},
|
||||||
rt::RegisterEHFrameSectionCustomDirectWrapperName},
|
{SAs.DeregisterEHFrame, rt::DeregisterEHFrameSectionWrapperName}}))
|
||||||
{SAs.DeregisterEHFrame,
|
|
||||||
rt::DeregisterEHFrameSectionCustomDirectWrapperName}}))
|
|
||||||
return std::move(Err);
|
return std::move(Err);
|
||||||
return std::make_unique<EPCGenericRTDyldMemoryManager>(EPC, std::move(SAs));
|
return std::make_unique<EPCGenericRTDyldMemoryManager>(EPC, std::move(SAs));
|
||||||
}
|
}
|
||||||
@@ -263,10 +263,12 @@ bool EPCGenericRTDyldMemoryManager::finalizeMemory(std::string *ErrMsg) {
|
|||||||
|
|
||||||
for (auto &Frame : ObjAllocs.UnfinalizedEHFrames)
|
for (auto &Frame : ObjAllocs.UnfinalizedEHFrames)
|
||||||
FR.Actions.push_back(
|
FR.Actions.push_back(
|
||||||
{{SAs.RegisterEHFrame,
|
{cantFail(
|
||||||
{ExecutorAddr(Frame.Addr), ExecutorAddrDiff(Frame.Size)}},
|
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
{SAs.DeregisterEHFrame,
|
SAs.RegisterEHFrame, Frame)),
|
||||||
{ExecutorAddr(Frame.Addr), ExecutorAddrDiff(Frame.Size)}}});
|
cantFail(
|
||||||
|
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
|
SAs.DeregisterEHFrame, Frame))});
|
||||||
|
|
||||||
// We'll also need to make an extra allocation for the eh-frame wrapper call
|
// We'll also need to make an extra allocation for the eh-frame wrapper call
|
||||||
// arguments.
|
// arguments.
|
||||||
|
|||||||
@@ -106,8 +106,8 @@ private:
|
|||||||
auto HeaderContent = G.allocateString(
|
auto HeaderContent = G.allocateString(
|
||||||
StringRef(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
|
StringRef(reinterpret_cast<const char *>(&Hdr), sizeof(Hdr)));
|
||||||
|
|
||||||
return G.createContentBlock(HeaderSection, HeaderContent,
|
return G.createContentBlock(HeaderSection, HeaderContent, ExecutorAddr(), 8,
|
||||||
orc::ExecutorAddr(), 8, 0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MaterializationUnit::Interface
|
static MaterializationUnit::Interface
|
||||||
@@ -880,10 +880,13 @@ Error MachOPlatform::MachOPlatformPlugin::registerEHAndTLVSections(
|
|||||||
if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
|
if (auto *EHFrameSection = G.findSectionByName(EHFrameSectionName)) {
|
||||||
jitlink::SectionRange R(*EHFrameSection);
|
jitlink::SectionRange R(*EHFrameSection);
|
||||||
if (!R.empty())
|
if (!R.empty())
|
||||||
G.allocActions().push_back({{MP.orc_rt_macho_register_ehframe_section,
|
G.allocActions().push_back(
|
||||||
R.getStart(), R.getSize()},
|
{cantFail(
|
||||||
{MP.orc_rt_macho_deregister_ehframe_section,
|
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
R.getStart(), R.getSize()}});
|
MP.orc_rt_macho_register_ehframe_section, R.getRange())),
|
||||||
|
cantFail(
|
||||||
|
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
|
MP.orc_rt_macho_deregister_ehframe_section, R.getRange()))});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a pointer to the thread data section if there is one. It will be used
|
// Get a pointer to the thread data section if there is one. It will be used
|
||||||
@@ -913,10 +916,13 @@ Error MachOPlatform::MachOPlatformPlugin::registerEHAndTLVSections(
|
|||||||
inconvertibleErrorCode());
|
inconvertibleErrorCode());
|
||||||
|
|
||||||
G.allocActions().push_back(
|
G.allocActions().push_back(
|
||||||
{{MP.orc_rt_macho_register_thread_data_section, R.getStart(),
|
{cantFail(
|
||||||
R.getSize()},
|
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
{MP.orc_rt_macho_deregister_thread_data_section, R.getStart(),
|
MP.orc_rt_macho_register_thread_data_section, R.getRange())),
|
||||||
R.getSize()}});
|
cantFail(
|
||||||
|
WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
|
MP.orc_rt_macho_deregister_thread_data_section,
|
||||||
|
R.getRange()))});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Error::success();
|
return Error::success();
|
||||||
@@ -963,8 +969,10 @@ Error MachOPlatform::MachOPlatformPlugin::registerEHSectionsPhase1(
|
|||||||
// Otherwise, add allocation actions to the graph to register eh-frames for
|
// Otherwise, add allocation actions to the graph to register eh-frames for
|
||||||
// this object.
|
// this object.
|
||||||
G.allocActions().push_back(
|
G.allocActions().push_back(
|
||||||
{{orc_rt_macho_register_ehframe_section, R.getStart(), R.getSize()},
|
{cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
{orc_rt_macho_deregister_ehframe_section, R.getStart(), R.getSize()}});
|
orc_rt_macho_register_ehframe_section, R.getRange())),
|
||||||
|
cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
|
||||||
|
orc_rt_macho_deregister_ehframe_section, R.getRange()))});
|
||||||
|
|
||||||
return Error::success();
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -756,7 +756,7 @@ void EHFrameRegistrationPlugin::modifyPassConfig(
|
|||||||
Error EHFrameRegistrationPlugin::notifyEmitted(
|
Error EHFrameRegistrationPlugin::notifyEmitted(
|
||||||
MaterializationResponsibility &MR) {
|
MaterializationResponsibility &MR) {
|
||||||
|
|
||||||
EHFrameRange EmittedRange;
|
ExecutorAddrRange EmittedRange;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
|
std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
|
||||||
|
|
||||||
@@ -765,7 +765,7 @@ Error EHFrameRegistrationPlugin::notifyEmitted(
|
|||||||
return Error::success();
|
return Error::success();
|
||||||
|
|
||||||
EmittedRange = EHFrameRangeItr->second;
|
EmittedRange = EHFrameRangeItr->second;
|
||||||
assert(EmittedRange.Addr && "eh-frame addr to register can not be null");
|
assert(EmittedRange.Start && "eh-frame addr to register can not be null");
|
||||||
InProcessLinks.erase(EHFrameRangeItr);
|
InProcessLinks.erase(EHFrameRangeItr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,7 +773,7 @@ Error EHFrameRegistrationPlugin::notifyEmitted(
|
|||||||
[&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
|
[&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
|
||||||
return Err;
|
return Err;
|
||||||
|
|
||||||
return Registrar->registerEHFrames(EmittedRange.Addr, EmittedRange.Size);
|
return Registrar->registerEHFrames(EmittedRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
Error EHFrameRegistrationPlugin::notifyFailed(
|
Error EHFrameRegistrationPlugin::notifyFailed(
|
||||||
@@ -784,7 +784,7 @@ Error EHFrameRegistrationPlugin::notifyFailed(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) {
|
Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) {
|
||||||
std::vector<EHFrameRange> RangesToRemove;
|
std::vector<ExecutorAddrRange> RangesToRemove;
|
||||||
|
|
||||||
ES.runSessionLocked([&] {
|
ES.runSessionLocked([&] {
|
||||||
auto I = EHFrameRanges.find(K);
|
auto I = EHFrameRanges.find(K);
|
||||||
@@ -798,10 +798,9 @@ Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) {
|
|||||||
while (!RangesToRemove.empty()) {
|
while (!RangesToRemove.empty()) {
|
||||||
auto RangeToRemove = RangesToRemove.back();
|
auto RangeToRemove = RangesToRemove.back();
|
||||||
RangesToRemove.pop_back();
|
RangesToRemove.pop_back();
|
||||||
assert(RangeToRemove.Addr && "Untracked eh-frame range must not be null");
|
assert(RangeToRemove.Start && "Untracked eh-frame range must not be null");
|
||||||
Err = joinErrors(
|
Err = joinErrors(std::move(Err),
|
||||||
std::move(Err),
|
Registrar->deregisterEHFrames(RangeToRemove));
|
||||||
Registrar->deregisterEHFrames(RangeToRemove.Addr, RangeToRemove.Size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err;
|
return Err;
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ const char *MemoryWriteUInt64sWrapperName =
|
|||||||
"__llvm_orc_bootstrap_mem_write_uint64s_wrapper";
|
"__llvm_orc_bootstrap_mem_write_uint64s_wrapper";
|
||||||
const char *MemoryWriteBuffersWrapperName =
|
const char *MemoryWriteBuffersWrapperName =
|
||||||
"__llvm_orc_bootstrap_mem_write_buffers_wrapper";
|
"__llvm_orc_bootstrap_mem_write_buffers_wrapper";
|
||||||
const char *RegisterEHFrameSectionCustomDirectWrapperName =
|
const char *RegisterEHFrameSectionWrapperName =
|
||||||
"__llvm_orc_bootstrap_register_ehframe_section_custom_direct_wrapper";
|
"__llvm_orc_bootstrap_register_ehframe_section_wrapper";
|
||||||
const char *DeregisterEHFrameSectionCustomDirectWrapperName =
|
const char *DeregisterEHFrameSectionWrapperName =
|
||||||
"__llvm_orc_bootstrap_deregister_ehframe_section_custom_direct_wrapper";
|
"__llvm_orc_bootstrap_deregister_ehframe_section_wrapper";
|
||||||
const char *RunAsMainWrapperName = "__llvm_orc_bootstrap_run_as_main_wrapper";
|
const char *RunAsMainWrapperName = "__llvm_orc_bootstrap_run_as_main_wrapper";
|
||||||
|
|
||||||
} // end namespace rt
|
} // end namespace rt
|
||||||
|
|||||||
@@ -105,10 +105,11 @@ static void registerJITLoaderGDBImpl(const char *ObjAddr, size_t Size) {
|
|||||||
extern "C" orc::shared::CWrapperFunctionResult
|
extern "C" orc::shared::CWrapperFunctionResult
|
||||||
llvm_orc_registerJITLoaderGDBAllocAction(const char *Data, size_t Size) {
|
llvm_orc_registerJITLoaderGDBAllocAction(const char *Data, size_t Size) {
|
||||||
using namespace orc::shared;
|
using namespace orc::shared;
|
||||||
return WrapperFunction<SPSError()>::handle(nullptr, 0,
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
[=]() -> Error {
|
Data, Size,
|
||||||
registerJITLoaderGDBImpl(Data,
|
[](ExecutorAddrRange R) {
|
||||||
Size);
|
registerJITLoaderGDBImpl(R.Start.toPtr<const char *>(),
|
||||||
|
R.size());
|
||||||
return Error::success();
|
return Error::success();
|
||||||
})
|
})
|
||||||
.release();
|
.release();
|
||||||
@@ -117,10 +118,12 @@ llvm_orc_registerJITLoaderGDBAllocAction(const char *Data, size_t Size) {
|
|||||||
extern "C" orc::shared::CWrapperFunctionResult
|
extern "C" orc::shared::CWrapperFunctionResult
|
||||||
llvm_orc_registerJITLoaderGDBWrapper(const char *Data, uint64_t Size) {
|
llvm_orc_registerJITLoaderGDBWrapper(const char *Data, uint64_t Size) {
|
||||||
using namespace orc::shared;
|
using namespace orc::shared;
|
||||||
return WrapperFunction<void(SPSExecutorAddrRange)>::handle(
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
Data, Size,
|
Data, Size,
|
||||||
[](ExecutorAddrRange R) {
|
[](ExecutorAddrRange R) {
|
||||||
registerJITLoaderGDBImpl(R.Start.toPtr<char *>(), R.size());
|
registerJITLoaderGDBImpl(R.Start.toPtr<const char *>(),
|
||||||
|
R.size());
|
||||||
|
return Error::success();
|
||||||
})
|
})
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,11 +71,10 @@ void addTo(StringMap<ExecutorAddr> &M) {
|
|||||||
shared::SPSMemoryAccessUInt64Write>);
|
shared::SPSMemoryAccessUInt64Write>);
|
||||||
M[rt::MemoryWriteBuffersWrapperName] =
|
M[rt::MemoryWriteBuffersWrapperName] =
|
||||||
ExecutorAddr::fromPtr(&writeBuffersWrapper);
|
ExecutorAddr::fromPtr(&writeBuffersWrapper);
|
||||||
M[rt::RegisterEHFrameSectionCustomDirectWrapperName] = ExecutorAddr::fromPtr(
|
M[rt::RegisterEHFrameSectionWrapperName] =
|
||||||
&llvm_orc_registerEHFrameSectionCustomDirectWrapper);
|
ExecutorAddr::fromPtr(&llvm_orc_registerEHFrameSectionWrapper);
|
||||||
M[rt::DeregisterEHFrameSectionCustomDirectWrapperName] =
|
M[rt::DeregisterEHFrameSectionWrapperName] =
|
||||||
ExecutorAddr::fromPtr(
|
ExecutorAddr::fromPtr(&llvm_orc_deregisterEHFrameSectionWrapper);
|
||||||
&llvm_orc_deregisterEHFrameSectionCustomDirectWrapper);
|
|
||||||
M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper);
|
M[rt::RunAsMainWrapperName] = ExecutorAddr::fromPtr(&runAsMainWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,42 +158,26 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
|
|||||||
} // end namespace orc
|
} // end namespace orc
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
extern "C" llvm::orc::shared::CWrapperFunctionResult
|
static Error registerEHFrameWrapper(ExecutorAddrRange EHFrame) {
|
||||||
llvm_orc_registerEHFrameSectionCustomDirectWrapper(
|
return llvm::orc::registerEHFrameSection(EHFrame.Start.toPtr<const void *>(),
|
||||||
const char *EHFrameSectionAddr, uint64_t Size) {
|
EHFrame.size());
|
||||||
if (auto Err = registerEHFrameSection(EHFrameSectionAddr, Size))
|
|
||||||
return WrapperFunctionResult::createOutOfBandError(toString(std::move(Err)))
|
|
||||||
.release();
|
|
||||||
return llvm::orc::shared::CWrapperFunctionResult();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" llvm::orc::shared::CWrapperFunctionResult
|
static Error deregisterEHFrameWrapper(ExecutorAddrRange EHFrame) {
|
||||||
llvm_orc_deregisterEHFrameSectionCustomDirectWrapper(
|
return llvm::orc::deregisterEHFrameSection(
|
||||||
const char *EHFrameSectionAddr, uint64_t Size) {
|
EHFrame.Start.toPtr<const void *>(), EHFrame.size());
|
||||||
if (auto Err = deregisterEHFrameSection(EHFrameSectionAddr, Size))
|
|
||||||
return WrapperFunctionResult::createOutOfBandError(toString(std::move(Err)))
|
|
||||||
.release();
|
|
||||||
return llvm::orc::shared::CWrapperFunctionResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
static Error registerEHFrameWrapper(ExecutorAddr Addr, uint64_t Size) {
|
|
||||||
return llvm::orc::registerEHFrameSection(Addr.toPtr<const void *>(), Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Error deregisterEHFrameWrapper(ExecutorAddr Addr, uint64_t Size) {
|
|
||||||
return llvm::orc::deregisterEHFrameSection(Addr.toPtr<const void *>(), Size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" orc::shared::CWrapperFunctionResult
|
extern "C" orc::shared::CWrapperFunctionResult
|
||||||
llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size) {
|
llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size) {
|
||||||
return WrapperFunction<SPSError(SPSExecutorAddr, uint64_t)>::handle(
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
Data, Size, registerEHFrameWrapper)
|
Data, Size, registerEHFrameWrapper)
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" orc::shared::CWrapperFunctionResult
|
extern "C" orc::shared::CWrapperFunctionResult
|
||||||
llvm_orc_deregisterEHFrameSectionWrapper(const char *Data, uint64_t Size) {
|
llvm_orc_deregisterEHFrameSectionWrapper(const char *Data, uint64_t Size) {
|
||||||
return WrapperFunction<SPSError(SPSExecutorAddr, uint64_t)>::handle(
|
return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
|
||||||
Data, Size, deregisterEHFrameWrapper)
|
Data, Size, deregisterEHFrameWrapper)
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Expected<ExecutorAddr> SimpleExecutorMemoryManager::allocate(uint64_t Size) {
|
|||||||
|
|
||||||
Error SimpleExecutorMemoryManager::finalize(tpctypes::FinalizeRequest &FR) {
|
Error SimpleExecutorMemoryManager::finalize(tpctypes::FinalizeRequest &FR) {
|
||||||
ExecutorAddr Base(~0ULL);
|
ExecutorAddr Base(~0ULL);
|
||||||
std::vector<tpctypes::WrapperFunctionCall> DeallocationActions;
|
std::vector<shared::WrapperFunctionCall> DeallocationActions;
|
||||||
size_t SuccessfulFinalizationActions = 0;
|
size_t SuccessfulFinalizationActions = 0;
|
||||||
|
|
||||||
if (FR.Segments.empty()) {
|
if (FR.Segments.empty()) {
|
||||||
@@ -52,8 +52,8 @@ Error SimpleExecutorMemoryManager::finalize(tpctypes::FinalizeRequest &FR) {
|
|||||||
Base = std::min(Base, Seg.Addr);
|
Base = std::min(Base, Seg.Addr);
|
||||||
|
|
||||||
for (auto &ActPair : FR.Actions)
|
for (auto &ActPair : FR.Actions)
|
||||||
if (ActPair.Deallocate.Func)
|
if (ActPair.Dealloc)
|
||||||
DeallocationActions.push_back(ActPair.Deallocate);
|
DeallocationActions.push_back(ActPair.Dealloc);
|
||||||
|
|
||||||
// Get the Allocation for this finalization.
|
// Get the Allocation for this finalization.
|
||||||
size_t AllocSize = 0;
|
size_t AllocSize = 0;
|
||||||
@@ -96,7 +96,7 @@ Error SimpleExecutorMemoryManager::finalize(tpctypes::FinalizeRequest &FR) {
|
|||||||
while (SuccessfulFinalizationActions)
|
while (SuccessfulFinalizationActions)
|
||||||
Err =
|
Err =
|
||||||
joinErrors(std::move(Err), FR.Actions[--SuccessfulFinalizationActions]
|
joinErrors(std::move(Err), FR.Actions[--SuccessfulFinalizationActions]
|
||||||
.Deallocate.runWithSPSRet());
|
.Dealloc.runWithSPSRetErrorMerged());
|
||||||
|
|
||||||
// Deallocate memory.
|
// Deallocate memory.
|
||||||
sys::MemoryBlock MB(AllocToDestroy.first, AllocToDestroy.second.Size);
|
sys::MemoryBlock MB(AllocToDestroy.first, AllocToDestroy.second.Size);
|
||||||
@@ -139,7 +139,7 @@ Error SimpleExecutorMemoryManager::finalize(tpctypes::FinalizeRequest &FR) {
|
|||||||
|
|
||||||
// Run finalization actions.
|
// Run finalization actions.
|
||||||
for (auto &ActPair : FR.Actions) {
|
for (auto &ActPair : FR.Actions) {
|
||||||
if (auto Err = ActPair.Finalize.runWithSPSRet())
|
if (auto Err = ActPair.Finalize.runWithSPSRetErrorMerged())
|
||||||
return BailOut(std::move(Err));
|
return BailOut(std::move(Err));
|
||||||
++SuccessfulFinalizationActions;
|
++SuccessfulFinalizationActions;
|
||||||
}
|
}
|
||||||
@@ -212,7 +212,7 @@ Error SimpleExecutorMemoryManager::deallocateImpl(void *Base, Allocation &A) {
|
|||||||
|
|
||||||
while (!A.DeallocationActions.empty()) {
|
while (!A.DeallocationActions.empty()) {
|
||||||
Err = joinErrors(std::move(Err),
|
Err = joinErrors(std::move(Err),
|
||||||
A.DeallocationActions.back().runWithSPSRet());
|
A.DeallocationActions.back().runWithSPSRetErrorMerged());
|
||||||
A.DeallocationActions.pop_back();
|
A.DeallocationActions.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ class JITLinkSlabAllocator final : public JITLinkMemoryManager {
|
|||||||
private:
|
private:
|
||||||
struct FinalizedAllocInfo {
|
struct FinalizedAllocInfo {
|
||||||
sys::MemoryBlock Mem;
|
sys::MemoryBlock Mem;
|
||||||
std::vector<AllocActionCall> DeallocActions;
|
std::vector<shared::WrapperFunctionCall> DeallocActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -22,8 +22,12 @@ namespace {
|
|||||||
|
|
||||||
orc::shared::CWrapperFunctionResult incrementWrapper(const char *ArgData,
|
orc::shared::CWrapperFunctionResult incrementWrapper(const char *ArgData,
|
||||||
size_t ArgSize) {
|
size_t ArgSize) {
|
||||||
return WrapperFunction<void(SPSExecutorAddr)>::handle(
|
return WrapperFunction<SPSError(SPSExecutorAddr)>::handle(
|
||||||
ArgData, ArgSize, [](ExecutorAddr A) { *A.toPtr<int *>() += 1; })
|
ArgData, ArgSize,
|
||||||
|
[](ExecutorAddr A) -> Error {
|
||||||
|
*A.toPtr<int *>() += 1;
|
||||||
|
return Error::success();
|
||||||
|
})
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,15 +41,7 @@ TEST(SimpleExecutorMemoryManagerTest, AllocFinalizeFree) {
|
|||||||
std::string HW = "Hello, world!";
|
std::string HW = "Hello, world!";
|
||||||
|
|
||||||
int FinalizeCounter = 0;
|
int FinalizeCounter = 0;
|
||||||
auto FinalizeCounterAddrArgBuffer =
|
|
||||||
orc::shared::detail::serializeViaSPSToWrapperFunctionResult<
|
|
||||||
SPSArgList<SPSExecutorAddr>>(ExecutorAddr::fromPtr(&FinalizeCounter));
|
|
||||||
|
|
||||||
int DeallocateCounter = 0;
|
int DeallocateCounter = 0;
|
||||||
auto DeallocateCounterAddrArgBuffer =
|
|
||||||
orc::shared::detail::serializeViaSPSToWrapperFunctionResult<
|
|
||||||
SPSArgList<SPSExecutorAddr>>(
|
|
||||||
ExecutorAddr::fromPtr(&DeallocateCounter));
|
|
||||||
|
|
||||||
tpctypes::FinalizeRequest FR;
|
tpctypes::FinalizeRequest FR;
|
||||||
FR.Segments.push_back(
|
FR.Segments.push_back(
|
||||||
@@ -55,13 +51,13 @@ TEST(SimpleExecutorMemoryManagerTest, AllocFinalizeFree) {
|
|||||||
{HW.data(), HW.size() + 1}});
|
{HW.data(), HW.size() + 1}});
|
||||||
FR.Actions.push_back(
|
FR.Actions.push_back(
|
||||||
{/* Finalize: */
|
{/* Finalize: */
|
||||||
{ExecutorAddr::fromPtr(incrementWrapper),
|
cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
|
||||||
{ExecutorAddr::fromPtr(FinalizeCounterAddrArgBuffer.data()),
|
ExecutorAddr::fromPtr(incrementWrapper),
|
||||||
ExecutorAddrDiff(FinalizeCounterAddrArgBuffer.size())}},
|
ExecutorAddr::fromPtr(&FinalizeCounter))),
|
||||||
/* Deallocate: */
|
/* Deallocate: */
|
||||||
{ExecutorAddr::fromPtr(incrementWrapper),
|
cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddr>>(
|
||||||
{ExecutorAddr::fromPtr(DeallocateCounterAddrArgBuffer.data()),
|
ExecutorAddr::fromPtr(incrementWrapper),
|
||||||
ExecutorAddrDiff(DeallocateCounterAddrArgBuffer.size())}}});
|
ExecutorAddr::fromPtr(&DeallocateCounter)))});
|
||||||
|
|
||||||
EXPECT_EQ(FinalizeCounter, 0);
|
EXPECT_EQ(FinalizeCounter, 0);
|
||||||
EXPECT_EQ(DeallocateCounter, 0);
|
EXPECT_EQ(DeallocateCounter, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user