14#define DEBUG_TYPE "orc"
18namespace rt_bootstrap {
21 assert(Allocations.
empty() &&
"shutdown not called?");
30 std::lock_guard<std::mutex> Lock(M);
31 assert(!Allocations.
count(MB.base()) &&
"Duplicate allocation addr");
32 Allocations[MB.base()].Size =
Size;
38 std::vector<shared::WrapperFunctionCall> DeallocationActions;
39 size_t SuccessfulFinalizationActions = 0;
46 return make_error<StringError>(
"Finalization actions attached to empty "
47 "finalization request",
54 for (
auto &ActPair : FR.
Actions)
56 DeallocationActions.push_back(ActPair.Dealloc);
61 std::lock_guard<std::mutex> Lock(M);
62 auto I = Allocations.
find(
Base.toPtr<
void *>());
63 if (
I == Allocations.
end())
64 return make_error<StringError>(
"Attempt to finalize unrecognized "
68 AllocSize =
I->second.Size;
69 I->second.DeallocationActions = std::move(DeallocationActions);
75 auto BailOut = [&](
Error Err) {
76 std::pair<void *, Allocation> AllocToDestroy;
80 std::lock_guard<std::mutex> Lock(M);
81 auto I = Allocations.
find(
Base.toPtr<
void *>());
84 if (
I == Allocations.
end())
87 make_error<StringError>(
"No allocation entry found "
91 AllocToDestroy = std::move(*
I);
96 while (SuccessfulFinalizationActions)
99 .Dealloc.runWithSPSRetErrorMerged());
114 return BailOut(make_error<StringError>(
115 formatv(
"Segment {0:x} content size ({1:x} bytes) "
116 "exceeds segment size ({2:x} bytes)",
117 Seg.Addr.getValue(), Seg.Content.size(), Seg.Size),
121 return BailOut(make_error<StringError>(
122 formatv(
"Segment {0:x} -- {1:x} crosses boundary of "
123 "allocation {2:x} -- {3:x}",
124 Seg.Addr.getValue(), SegEnd.
getValue(),
Base.getValue(),
128 char *Mem = Seg.Addr.toPtr<
char *>();
129 if (!Seg.Content.empty())
130 memcpy(Mem, Seg.Content.data(), Seg.Content.size());
131 memset(Mem + Seg.Content.size(), 0, Seg.Size - Seg.Content.size());
132 assert(Seg.Size <= std::numeric_limits<size_t>::max());
134 {Mem,
static_cast<size_t>(Seg.Size)},
142 for (
auto &ActPair : FR.
Actions) {
143 if (
auto Err = ActPair.Finalize.runWithSPSRetErrorMerged())
144 return BailOut(std::move(Err));
145 ++SuccessfulFinalizationActions;
152 const std::vector<ExecutorAddr> &Bases) {
153 std::vector<std::pair<void *, Allocation>> AllocPairs;
154 AllocPairs.reserve(Bases.size());
159 std::lock_guard<std::mutex> Lock(M);
160 for (
auto &
Base : Bases) {
161 auto I = Allocations.
find(
Base.toPtr<
void *>());
164 if (
I != Allocations.
end()) {
165 AllocPairs.push_back(std::move(*
I));
170 make_error<StringError>(
"No allocation entry found "
177 while (!AllocPairs.empty()) {
178 auto &
P = AllocPairs.back();
179 Err =
joinErrors(std::move(Err), deallocateImpl(
P.first,
P.second));
180 AllocPairs.pop_back();
190 std::lock_guard<std::mutex> Lock(M);
191 AM = std::move(Allocations);
196 Err =
joinErrors(std::move(Err), deallocateImpl(KV.first, KV.second));
211Error SimpleExecutorMemoryManager::deallocateImpl(
void *
Base, Allocation &
A) {
214 while (!
A.DeallocationActions.empty()) {
216 A.DeallocationActions.back().runWithSPSRetErrorMerged());
217 A.DeallocationActions.pop_back();
228SimpleExecutorMemoryManager::reserveWrapper(
const char *ArgData,
230 return shared::WrapperFunction<
232 handle(ArgData, ArgSize,
239SimpleExecutorMemoryManager::finalizeWrapper(
const char *ArgData,
241 return shared::WrapperFunction<
243 handle(ArgData, ArgSize,
250SimpleExecutorMemoryManager::deallocateWrapper(
const char *ArgData,
252 return shared::WrapperFunction<
254 handle(ArgData, ArgSize,
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_UNLIKELY(EXPR)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represents an address in the executor process.
uint64_t getValue() const
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
Error finalize(tpctypes::FinalizeRequest &FR)
Error deallocate(const std::vector< ExecutorAddr > &Bases)
Error shutdown() override
Expected< ExecutorAddr > allocate(uint64_t Size)
virtual ~SimpleExecutorMemoryManager()
void addBootstrapSymbols(StringMap< ExecutorAddr > &M) override
This class encapsulates the notion of a memory block which has an address and a size.
static std::error_code releaseMappedMemory(MemoryBlock &Block)
This method releases a block of memory that was allocated with the allocateMappedMemory method.
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)
This method allocates a block of memory that is suitable for loading dynamically generated code (e....
static void InvalidateInstructionCache(const void *Addr, size_t Len)
InvalidateInstructionCache - Before the JIT can run a block of code that has been emitted it must inv...
static std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
This method sets the protection flags for a block of memory to the state specified by /p Flags.
shared::SPSExpected< shared::SPSExecutorAddr >(shared::SPSExecutorAddr, uint64_t) SPSSimpleExecutorMemoryManagerReserveSignature
const char * SimpleExecutorMemoryManagerFinalizeWrapperName
const char * SimpleExecutorMemoryManagerDeallocateWrapperName
const char * SimpleExecutorMemoryManagerReserveWrapperName
shared::SPSError(shared::SPSExecutorAddr, shared::SPSFinalizeRequest) SPSSimpleExecutorMemoryManagerFinalizeSignature
const char * SimpleExecutorMemoryManagerInstanceName
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSSimpleExecutorMemoryManagerDeallocateSignature
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
uint64_t ExecutorAddrDiff
sys::Memory::ProtectionFlags toSysMemoryProtectionFlags(MemProt MP)
Convert a MemProt value to a corresponding sys::Memory::ProtectionFlags value.
This is an optimization pass for GlobalISel generic memory operations.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::vector< SegFinalizeRequest > Segments
shared::AllocActions Actions