llvm-project/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp
Lang Hames 0e940d55f8 [ORC] Add TargetProcessControl and TPCIndirectionUtils APIs.
TargetProcessControl is a new API for communicating with JIT target processes.
It supports memory allocation and access, and inspection of some process
properties, e.g. the target proces triple and page size.

Centralizing these APIs allows utilities written against TargetProcessControl
to remain independent of the communication procotol with the target process
(which may be direct memory access/allocation for in-process JITing, or may
involve some form of IPC or RPC).

An initial set of TargetProcessControl-based utilities for lazy compilation is
provided by the TPCIndirectionUtils class.

An initial implementation of TargetProcessControl for in-process JITing
is provided by the SelfTargetProcessControl class.

An example program showing how the APIs can be used is provided in
llvm/examples/OrcV2Examples/LLJITWithTargetProcessControl.
2020-07-16 15:09:13 -07:00

80 lines
2.7 KiB
C++

//===------ TargetProcessControl.cpp -- Target process control APIs -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/TargetProcessControl.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Process.h"
#include <mutex>
namespace llvm {
namespace orc {
TargetProcessControl::MemoryAccess::~MemoryAccess() {}
TargetProcessControl::TargetProcessControl(Triple TT, unsigned PageSize)
: TT(std::move(TT)), PageSize(PageSize) {}
TargetProcessControl::~TargetProcessControl() {}
SelfTargetProcessControl::SelfTargetProcessControl(Triple TT, unsigned PageSize)
: TargetProcessControl(std::move(TT), PageSize) {
this->MemMgr = IPMM.get();
this->MemAccess = this;
}
Expected<std::unique_ptr<SelfTargetProcessControl>>
SelfTargetProcessControl::Create() {
auto PageSize = sys::Process::getPageSize();
if (!PageSize)
return PageSize.takeError();
Triple TT(sys::getProcessTriple());
return std::make_unique<SelfTargetProcessControl>(std::move(TT), *PageSize);
}
void SelfTargetProcessControl::writeUInt8s(ArrayRef<UInt8Write> Ws,
WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*jitTargetAddressToPointer<uint8_t *>(W.Address) = W.Value;
OnWriteComplete(Error::success());
}
void SelfTargetProcessControl::writeUInt16s(ArrayRef<UInt16Write> Ws,
WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*jitTargetAddressToPointer<uint16_t *>(W.Address) = W.Value;
OnWriteComplete(Error::success());
}
void SelfTargetProcessControl::writeUInt32s(ArrayRef<UInt32Write> Ws,
WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*jitTargetAddressToPointer<uint32_t *>(W.Address) = W.Value;
OnWriteComplete(Error::success());
}
void SelfTargetProcessControl::writeUInt64s(ArrayRef<UInt64Write> Ws,
WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
*jitTargetAddressToPointer<uint64_t *>(W.Address) = W.Value;
OnWriteComplete(Error::success());
}
void SelfTargetProcessControl::writeBuffers(ArrayRef<BufferWrite> Ws,
WriteResultFn OnWriteComplete) {
for (auto &W : Ws)
memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
W.Buffer.size());
OnWriteComplete(Error::success());
}
} // end namespace orc
} // end namespace llvm