Go to the documentation of this file.
14 #define DEBUG_TYPE "orc"
18 namespace 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 "
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 memcpy(Mem, Seg.Content.data(), Seg.Content.size());
130 memset(Mem + Seg.Content.size(), 0, Seg.Size - Seg.Content.size());
133 {Mem,
static_cast<size_t>(Seg.Size)},
141 for (
auto &ActPair : FR.
Actions) {
142 if (
auto Err = ActPair.Finalize.runWithSPSRetErrorMerged())
144 ++SuccessfulFinalizationActions;
151 const std::vector<ExecutorAddr> &Bases) {
152 std::vector<std::pair<void *, Allocation>> AllocPairs;
153 AllocPairs.reserve(Bases.size());
158 std::lock_guard<std::mutex>
Lock(M);
159 for (
auto &
Base : Bases) {
160 auto I = Allocations.
find(
Base.toPtr<
void *>());
163 if (
I != Allocations.
end()) {
169 make_error<StringError>(
"No allocation entry found "
176 while (!AllocPairs.empty()) {
177 auto &
P = AllocPairs.back();
179 AllocPairs.pop_back();
189 std::lock_guard<std::mutex>
Lock(M);
210 Error SimpleExecutorMemoryManager::deallocateImpl(
void *
Base, Allocation &A) {
213 while (!A.DeallocationActions.empty()) {
215 A.DeallocationActions.back().runWithSPSRetErrorMerged());
216 A.DeallocationActions.pop_back();
227 SimpleExecutorMemoryManager::reserveWrapper(
const char *ArgData,
229 return shared::WrapperFunction<
238 SimpleExecutorMemoryManager::finalizeWrapper(
const char *ArgData,
240 return shared::WrapperFunction<
249 SimpleExecutorMemoryManager::deallocateWrapper(
const char *ArgData,
251 return shared::WrapperFunction<
Represents an address in the executor process.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
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 ErrorSuccess success()
Create a success value.
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 std::error_code releaseMappedMemory(MemoryBlock &Block)
This method releases a block of memory that was allocated with the allocateMappedMemory method.
uint64_t getValue() const
bool erase(const KeyT &Val)
This class encapsulates the notion of a memory block which has an address and a size.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
shared::SPSError(shared::SPSExecutorAddr, shared::SPSFinalizeRequest) SPSSimpleExecutorMemoryManagerFinalizeSignature
Tagged union holding either a T or a Error.
shared::AllocActions Actions
then ret i32 result Tail recursion elimination should handle
const char * SimpleExecutorMemoryManagerInstanceName
void addBootstrapSymbols(StringMap< ExecutorAddr > &M) override
const char * SimpleExecutorMemoryManagerFinalizeWrapperName
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
const char * SimpleExecutorMemoryManagerDeallocateWrapperName
sys::Memory::ProtectionFlags fromWireProtectionFlags(WireProtectionFlags WPF)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
shared::SPSExpected< shared::SPSExecutorAddr >(shared::SPSExecutorAddr, uint64_t) SPSSimpleExecutorMemoryManagerReserveSignature
uint64_t ExecutorAddrDiff
virtual ~SimpleExecutorMemoryManager()
static ExecutorAddr fromPtr(T *Value)
Create an ExecutorAddr from the given pointer.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Error finalize(tpctypes::FinalizeRequest &FR)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Error joinErrors(Error E1, Error E2)
Concatenate errors.
iterator find(const_arg_type_t< KeyT > Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
std::vector< SegFinalizeRequest > Segments
Error deallocate(const std::vector< ExecutorAddr > &Bases)
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
LLVM_NODISCARD bool empty() const
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Lightweight error class with error context and mandatory checking.
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.
Align max(MaybeAlign Lhs, Align Rhs)
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
Expected< ExecutorAddr > allocate(uint64_t Size)
Error shutdown() override
const char * SimpleExecutorMemoryManagerReserveWrapperName
#define LLVM_UNLIKELY(EXPR)
shared::SPSError(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSSimpleExecutorMemoryManagerDeallocateSignature