15#define DEBUG_TYPE "orc" 
   19namespace rt_bootstrap {
 
   22  assert(Slabs.empty() && 
"shutdown not called?");
 
 
   31  std::lock_guard<std::mutex> Lock(M);
 
   32  assert(!Slabs.count(MB.base()) && 
"Duplicate allocation addr");
 
   33  Slabs[MB.base()].Size = 
Size;
 
 
   39  std::vector<shared::WrapperFunctionCall> DeallocationActions;
 
   47                                     "finalization request",
 
   53  std::vector<sys::MemoryBlock> MBsToReset;
 
   55    for (
auto &MB : MBsToReset)
 
   65    RR.
End = std::max(RR.
End, Seg.Addr + Seg.Size);
 
   70          formatv(
"Segment {0:x} content size ({1:x} bytes) " 
   71                  "exceeds segment size ({2:x} bytes)",
 
   72                  Seg.Addr.getValue(), Seg.Content.size(), Seg.Size),
 
   77          formatv(
"Segment {0:x} -- {1:x} crosses boundary of " 
   78                  "allocation {2:x} -- {3:x}",
 
   82    char *Mem = Seg.Addr.toPtr<
char *>();
 
   83    if (!Seg.Content.empty())
 
   84      memcpy(Mem, Seg.Content.data(), Seg.Content.size());
 
   85    memset(Mem + Seg.Content.size(), 0, Seg.Size - Seg.Content.size());
 
   86    assert(Seg.Size <= std::numeric_limits<size_t>::max());
 
   93    MBsToReset.push_back(MB);
 
   99  auto DeallocActions = runFinalizeActions(FR.
Actions);
 
  101    return DeallocActions.takeError();
 
  104    std::lock_guard<std::mutex> Lock(M);
 
  105    auto Region = createRegionInfo(RR, 
"In initialize");
 
  107      return Region.takeError();
 
  108    Region->DeallocActions = std::move(*DeallocActions);
 
 
  118    const std::vector<ExecutorAddr> &InitKeys) {
 
  122    std::vector<shared::WrapperFunctionCall> DeallocActions;
 
  124      std::scoped_lock<std::mutex> Lock(M);
 
  125      auto Slab = getSlabInfo(KeyAddr, 
"In deinitialize");
 
  127        Err = 
joinErrors(std::move(Err), Slab.takeError());
 
  131      auto RI = getRegionInfo(*Slab, KeyAddr, 
"In deinitialize");
 
  133        Err = 
joinErrors(std::move(Err), RI.takeError());
 
  137      DeallocActions = std::move(RI->DeallocActions);
 
  141                     runDeallocActions(std::move(DeallocActions)));
 
 
  148    const std::vector<ExecutorAddr> &Bases) {
 
  153    std::vector<shared::WrapperFunctionCall> DeallocActions;
 
  157      std::scoped_lock<std::mutex> Lock(M);
 
  159      auto SlabI = Slabs.find(
Base.toPtr<
void *>());
 
  160      if (SlabI == Slabs.end()) {
 
  164                                        " is not part of any reserved " 
  170      auto &Slab = SlabI->second;
 
  172      for (
auto &[Addr, 
Region] : Slab.Regions)
 
  175      MB = {
Base.toPtr<
void *>(), Slab.Size};
 
  180    Err = 
joinErrors(std::move(Err), runDeallocActions(DeallocActions));
 
 
  191  std::vector<ExecutorAddr> Bases;
 
  193    std::scoped_lock<std::mutex> Lock(M);
 
  194    for (
auto &[
Base, Slab] : Slabs)
 
 
  216  auto MakeBadSlabError = [&]() {
 
  218        Context + 
", address " + 
formatv(
"{0:x}", 
A) +
 
  219            " is not part of any reserved address range",
 
  223  auto I = Slabs.upper_bound(
A.toPtr<
void *>());
 
  224  if (
I == Slabs.begin())
 
  225    return MakeBadSlabError();
 
  229    return MakeBadSlabError();
 
  235SimpleExecutorMemoryManager::getSlabInfo(ExecutorAddrRange R,
 
  237  auto MakeBadSlabError = [&]() {
 
  239        Context + 
", range " + 
formatv(
"{0:x}", R) +
 
  240            " is not part of any reserved address range",
 
  244  auto I = Slabs.upper_bound(R.Start.toPtr<
void *>());
 
  245  if (
I == Slabs.begin())
 
  246    return MakeBadSlabError();
 
  250    return MakeBadSlabError();
 
  255Expected<SimpleExecutorMemoryManager::RegionInfo &>
 
  256SimpleExecutorMemoryManager::createRegionInfo(ExecutorAddrRange R,
 
  259  auto Slab = getSlabInfo(R, 
Context);
 
  261    return Slab.takeError();
 
  263  auto MakeBadRegionError = [&](ExecutorAddrRange 
Other, 
bool Prev) {
 
  266                                       (Prev ? 
"previous" : 
"following") +
 
  271  auto I = Slab->Regions.upper_bound(
R.Start);
 
  272  if (
I != Slab->Regions.begin()) {
 
  273    auto J = std::prev(
I);
 
  274    ExecutorAddrRange PrevRange(J->first, J->second.Size);
 
  275    if (PrevRange.overlaps(R))
 
  276      return MakeBadRegionError(PrevRange, 
true);
 
  278  if (
I != Slab->Regions.end()) {
 
  279    ExecutorAddrRange NextRange(
I->first, 
I->second.Size);
 
  280    if (NextRange.overlaps(R))
 
  281      return MakeBadRegionError(NextRange, 
false);
 
  284  auto &RInfo = Slab->Regions[
R.Start];
 
  285  RInfo.Size = 
R.size();
 
  289Expected<SimpleExecutorMemoryManager::RegionInfo &>
 
  290SimpleExecutorMemoryManager::getRegionInfo(SlabInfo &Slab, ExecutorAddr 
A,
 
  292  auto I = Slab.Regions.find(
A);
 
  293  if (
I == Slab.Regions.end())
 
  296            " does not correspond to the start of any initialized region",
 
  302Expected<SimpleExecutorMemoryManager::RegionInfo &>
 
  303SimpleExecutorMemoryManager::getRegionInfo(ExecutorAddr 
A, StringRef 
Context) {
 
  304  auto Slab = getSlabInfo(
A, 
Context);
 
  306    return Slab.takeError();
 
  308  return getRegionInfo(*Slab, 
A, 
Context);
 
  311llvm::orc::shared::CWrapperFunctionResult
 
  312SimpleExecutorMemoryManager::reserveWrapper(
const char *ArgData,
 
  314  return shared::WrapperFunction<rt::SPSSimpleRemoteMemoryMapReserveSignature>::
 
  315      handle(ArgData, ArgSize,
 
  321llvm::orc::shared::CWrapperFunctionResult
 
  322SimpleExecutorMemoryManager::initializeWrapper(
const char *ArgData,
 
  325      WrapperFunction<rt::SPSSimpleRemoteMemoryMapInitializeSignature>::handle(
 
  332llvm::orc::shared::CWrapperFunctionResult
 
  333SimpleExecutorMemoryManager::deinitializeWrapper(
const char *ArgData,
 
  335  return shared::WrapperFunction<
 
  337      handle(ArgData, ArgSize,
 
  343llvm::orc::shared::CWrapperFunctionResult
 
  344SimpleExecutorMemoryManager::releaseWrapper(
const char *ArgData,
 
  346  return shared::WrapperFunction<rt::SPSSimpleRemoteMemoryMapReleaseSignature>::
 
  347      handle(ArgData, ArgSize,
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_UNLIKELY(EXPR)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
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",...
StringRef - Represent a constant reference to a string, i.e.
Represents an address in the executor process.
static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap=UnwrapFn())
Create an ExecutorAddr from the given pointer.
std::enable_if_t< std::is_pointer< T >::value, T > toPtr(WrapFn &&Wrap=WrapFn()) const
Cast this ExecutorAddr to a pointer of the given type.
Error deinitialize(const std::vector< ExecutorAddr > &InitKeys)
Error release(const std::vector< ExecutorAddr > &Bases)
~SimpleExecutorMemoryManager() override
Error shutdown() override
Expected< ExecutorAddr > reserve(uint64_t Size)
Expected< ExecutorAddr > initialize(tpctypes::FinalizeRequest &FR)
void addBootstrapSymbols(StringMap< ExecutorAddr > &M) override
This class encapsulates the notion of a memory block which has an address and a size.
static LLVM_ABI 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.
static LLVM_ABI std::error_code releaseMappedMemory(MemoryBlock &Block)
This method releases a block of memory that was allocated with the allocateMappedMemory method.
static LLVM_ABI 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 LLVM_ABI 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....
LLVM_ABI const char * SimpleExecutorMemoryManagerInitializeWrapperName
LLVM_ABI const char * SimpleExecutorMemoryManagerReserveWrapperName
LLVM_ABI const char * SimpleExecutorMemoryManagerReleaseWrapperName
LLVM_ABI const char * SimpleExecutorMemoryManagerDeinitializeWrapperName
shared::SPSError( shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSExecutorAddr >) SPSSimpleRemoteMemoryMapDeinitializeSignature
LLVM_ABI const char * SimpleExecutorMemoryManagerInstanceName
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.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
OutputIt copy(R &&Range, OutputIt Out)
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Represents an address range in the exceutor process.
ExecutorAddrDiff size() const
bool contains(ExecutorAddr Addr) const
std::vector< SegFinalizeRequest > Segments
shared::AllocActions Actions