brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · f8a2bd3 Raw
169 lines · cpp
1//===------ SelfExecutorProcessControl.cpp -- EPC for in-process JITs -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"10 11#include "llvm/ExecutionEngine/Orc/Core.h"12#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h"13#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"14#include "llvm/Support/DynamicLibrary.h"15#include "llvm/Support/Process.h"16#include "llvm/TargetParser/Host.h"17 18#define DEBUG_TYPE "orc"19 20namespace llvm::orc {21 22SelfExecutorProcessControl::SelfExecutorProcessControl(23    std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,24    Triple TargetTriple, unsigned PageSize,25    std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)26    : ExecutorProcessControl(std::move(SSP), std::move(D)),27      IPMA(TargetTriple.isArch64Bit()) {28 29  OwnedMemMgr = std::move(MemMgr);30  if (!OwnedMemMgr)31    OwnedMemMgr = std::make_unique<jitlink::InProcessMemoryManager>(32        sys::Process::getPageSizeEstimate());33 34  this->TargetTriple = std::move(TargetTriple);35  this->PageSize = PageSize;36  this->MemMgr = OwnedMemMgr.get();37  this->MemAccess = &IPMA;38  this->DylibMgr = this;39  this->JDI = {ExecutorAddr::fromPtr(jitDispatchViaWrapperFunctionManager),40               ExecutorAddr::fromPtr(this)};41 42  if (this->TargetTriple.isOSBinFormatMachO())43    GlobalManglingPrefix = '_';44 45  addDefaultBootstrapValuesForHostProcess(BootstrapMap, BootstrapSymbols);46 47#ifdef __APPLE__48  // FIXME: Don't add an UnwindInfoManager by default -- it's redundant when49  //        the ORC runtime is loaded. We'll need a way to document this and50  //        allow clients to choose.51  if (UnwindInfoManager::TryEnable())52    UnwindInfoManager::addBootstrapSymbols(this->BootstrapSymbols);53#endif // __APPLE__54}55 56Expected<std::unique_ptr<SelfExecutorProcessControl>>57SelfExecutorProcessControl::Create(58    std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,59    std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {60 61  if (!SSP)62    SSP = std::make_shared<SymbolStringPool>();63 64  if (!D)65    D = std::make_unique<InPlaceTaskDispatcher>();66 67  auto PageSize = sys::Process::getPageSize();68  if (!PageSize)69    return PageSize.takeError();70 71  Triple TT(sys::getProcessTriple());72 73  return std::make_unique<SelfExecutorProcessControl>(74      std::move(SSP), std::move(D), std::move(TT), *PageSize,75      std::move(MemMgr));76}77 78Expected<tpctypes::DylibHandle>79SelfExecutorProcessControl::loadDylib(const char *DylibPath) {80  std::string ErrMsg;81  auto Dylib = sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg);82  if (!Dylib.isValid())83    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());84  return ExecutorAddr::fromPtr(Dylib.getOSSpecificHandle());85}86 87void SelfExecutorProcessControl::lookupSymbolsAsync(88    ArrayRef<LookupRequest> Request,89    DylibManager::SymbolLookupCompleteFn Complete) {90  std::vector<tpctypes::LookupResult> R;91 92  for (auto &Elem : Request) {93    sys::DynamicLibrary Dylib(Elem.Handle.toPtr<void *>());94    R.push_back(tpctypes::LookupResult());95    for (auto &KV : Elem.Symbols) {96      auto &Sym = KV.first;97      std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,98                      (*Sym).size() - !!GlobalManglingPrefix);99      void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str());100      if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol)101        R.back().emplace_back();102      else103        // FIXME: determine accurate JITSymbolFlags.104        R.back().emplace_back(ExecutorSymbolDef(ExecutorAddr::fromPtr(Addr),105                                                JITSymbolFlags::Exported));106    }107  }108 109  Complete(std::move(R));110}111 112Expected<int32_t>113SelfExecutorProcessControl::runAsMain(ExecutorAddr MainFnAddr,114                                      ArrayRef<std::string> Args) {115  using MainTy = int (*)(int, char *[]);116  return orc::runAsMain(MainFnAddr.toPtr<MainTy>(), Args);117}118 119Expected<int32_t>120SelfExecutorProcessControl::runAsVoidFunction(ExecutorAddr VoidFnAddr) {121  using VoidTy = int (*)();122  return orc::runAsVoidFunction(VoidFnAddr.toPtr<VoidTy>());123}124 125Expected<int32_t>126SelfExecutorProcessControl::runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) {127  using IntTy = int (*)(int);128  return orc::runAsIntFunction(IntFnAddr.toPtr<IntTy>(), Arg);129}130 131void SelfExecutorProcessControl::callWrapperAsync(ExecutorAddr WrapperFnAddr,132                                                  IncomingWFRHandler SendResult,133                                                  ArrayRef<char> ArgBuffer) {134  using WrapperFnTy =135      shared::CWrapperFunctionResult (*)(const char *Data, size_t Size);136  auto *WrapperFn = WrapperFnAddr.toPtr<WrapperFnTy>();137  SendResult(WrapperFn(ArgBuffer.data(), ArgBuffer.size()));138}139 140Error SelfExecutorProcessControl::disconnect() {141  D->shutdown();142  return Error::success();143}144 145shared::CWrapperFunctionResult146SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(147    void *Ctx, const void *FnTag, const char *Data, size_t Size) {148 149  LLVM_DEBUG({150    dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size151           << " byte payload.\n";152  });153 154  std::promise<shared::WrapperFunctionResult> ResultP;155  auto ResultF = ResultP.get_future();156  static_cast<SelfExecutorProcessControl *>(Ctx)157      ->getExecutionSession()158      .runJITDispatchHandler(159          [ResultP = std::move(ResultP)](160              shared::WrapperFunctionResult Result) mutable {161            ResultP.set_value(std::move(Result));162          },163          ExecutorAddr::fromPtr(FnTag), {Data, Size});164 165  return ResultF.get().release();166}167 168} // namespace llvm::orc169