20#define DEBUG_TYPE "orc"
31#if LLVM_ENABLE_THREADS
32void SimpleRemoteEPCServer::ThreadDispatcher::dispatch(
35 std::lock_guard<std::mutex> Lock(DispatchMutex);
41 std::thread([
this, Work = std::move(Work)]()
mutable {
43 std::lock_guard<std::mutex> Lock(DispatchMutex);
45 OutstandingCV.notify_all();
49void SimpleRemoteEPCServer::ThreadDispatcher::shutdown() {
50 std::unique_lock<std::mutex> Lock(DispatchMutex);
52 OutstandingCV.wait(Lock, [
this]() {
return Outstanding == 0; });
68 dbgs() <<
"SimpleRemoteEPCServer::handleMessage: opc = ";
72 assert(SeqNo == 0 &&
"Non-zero SeqNo for Setup?");
73 assert(!TagAddr &&
"Non-zero TagAddr for Setup?");
77 assert(SeqNo == 0 &&
"Non-zero SeqNo for Hangup?");
78 assert(!TagAddr &&
"Non-zero TagAddr for Hangup?");
82 assert(!TagAddr &&
"Non-zero TagAddr for Result?");
85 dbgs() <<
"CallWrapper";
88 dbgs() <<
", seqno = " << SeqNo <<
", tag-addr = " << TagAddr
89 <<
", arg-buffer = " <<
formatv(
"{0:x}", ArgBytes.
size())
93 using UT = std::underlying_type_t<SimpleRemoteEPCOpcode>;
95 return make_error<StringError>(
"Unexpected opcode",
101 return make_error<StringError>(
"Unexpected Setup opcode",
106 if (
auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
107 return std::move(Err);
110 handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));
117 std::unique_lock<std::mutex> Lock(ServerStateMutex);
118 ShutdownCV.wait(Lock, [
this]() {
return RunState == ServerShutDown; });
119 return std::move(ShutdownErr);
126 std::lock_guard<std::mutex> Lock(ServerStateMutex);
127 std::swap(TmpPending, PendingJITDispatchResults);
128 RunState = ServerShuttingDown;
132 for (
auto &KV : TmpPending)
133 KV.second->set_value(
140 while (!Services.empty()) {
142 joinErrors(std::move(ShutdownErr), Services.back()->shutdown());
146 std::lock_guard<std::mutex> Lock(ServerStateMutex);
147 ShutdownErr =
joinErrors(std::move(ShutdownErr), std::move(Err));
148 RunState = ServerShutDown;
149 ShutdownCV.notify_all();
157 dbgs() <<
"SimpleRemoteEPCServer::sendMessage: opc = ";
161 assert(SeqNo == 0 &&
"Non-zero SeqNo for Setup?");
162 assert(!TagAddr &&
"Non-zero TagAddr for Setup?");
166 assert(SeqNo == 0 &&
"Non-zero SeqNo for Hangup?");
167 assert(!TagAddr &&
"Non-zero TagAddr for Hangup?");
171 assert(!TagAddr &&
"Non-zero TagAddr for Result?");
174 dbgs() <<
"CallWrapper";
177 dbgs() <<
", seqno = " << SeqNo <<
", tag-addr = " << TagAddr
178 <<
", arg-buffer = " <<
formatv(
"{0:x}", ArgBytes.
size())
181 auto Err =
T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes);
184 dbgs() <<
" \\--> SimpleRemoteEPC::sendMessage failed\n";
189Error SimpleRemoteEPCServer::sendSetupMessage(
190 StringMap<std::vector<char>> BootstrapMap,
193 using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;
195 std::vector<char> SetupPacket;
206 "Dispatch context name should not be set");
208 "Dispatch function name should not be set");
218 auto SetupPacketBytes =
221 if (!SPSSerialize::serialize(OB, EI))
222 return make_error<StringError>(
"Could not send setup packet",
226 {SetupPacketBytes.data(), SetupPacketBytes.size()});
229Error SimpleRemoteEPCServer::handleResult(
232 std::promise<shared::WrapperFunctionResult> *
P =
nullptr;
234 std::lock_guard<std::mutex> Lock(ServerStateMutex);
235 auto I = PendingJITDispatchResults.
find(SeqNo);
236 if (
I == PendingJITDispatchResults.
end())
237 return make_error<StringError>(
"No call for sequence number " +
241 PendingJITDispatchResults.
erase(
I);
245 memcpy(
R.data(), ArgBytes.
data(), ArgBytes.
size());
246 P->set_value(std::move(R));
250void SimpleRemoteEPCServer::handleCallWrapper(
253 D->dispatch([
this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() {
256 auto *Fn = TagAddr.
toPtr<WrapperFnTy>();
258 Fn(ArgBytes.
data(), ArgBytes.
size()));
261 {ResultBytes.data(), ResultBytes.size()}))
262 ReportError(std::move(Err));
267SimpleRemoteEPCServer::doJITDispatch(
const void *FnTag,
const char *ArgData,
270 std::promise<shared::WrapperFunctionResult> ResultP;
271 auto ResultF = ResultP.get_future();
273 std::lock_guard<std::mutex> Lock(ServerStateMutex);
274 if (RunState != ServerRunning)
276 "jit_dispatch not available (EPC server shut down)");
278 SeqNo = getNextSeqNo();
279 assert(!PendingJITDispatchResults.
count(SeqNo) &&
"SeqNo already in use");
280 PendingJITDispatchResults[SeqNo] = &ResultP;
285 ReportError(std::move(Err));
287 return ResultF.get();
291SimpleRemoteEPCServer::jitDispatchEntry(
void *DispatchCtx,
const void *FnTag,
292 const char *ArgData,
size_t ArgSize) {
294 ->doJITDispatch(FnTag, ArgData, ArgSize)
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
Provides a library for accessing information about this process and other processes on the operating ...
llvm::orc::shared::CWrapperFunctionResult llvm_orc_deregisterEHFrameSectionWrapper(const char *Data, uint64_t Size)
llvm::orc::shared::CWrapperFunctionResult llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
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.
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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.
virtual ~ExecutorBootstrapService()
A simple EPC server implementation.
static StringMap< ExecutorAddr > defaultBootstrapSymbols()
Expected< HandleMessageAction > handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes) override
Call to handle an incoming message.
void handleDisconnect(Error Err) override
Handle a disconnection from the underlying transport.
Error waitForDisconnect()
A utility class for serializing to a blob from a variadic list.
Output char buffer with overflow check.
C++ wrapper function result: Same as CWrapperFunctionResult but auto-releases memory.
static WrapperFunctionResult allocate(size_t Size)
Create a WrapperFunctionResult with the given size and return a pointer to the underlying memory.
CWrapperFunctionResult release()
Release ownership of the contained CWrapperFunctionResult.
static WrapperFunctionResult createOutOfBandError(const char *Msg)
Create an out-of-band error by copying the given string.
static Expected< unsigned > getPageSize()
Get the process's page size.
unique_function is a type-erasing functor similar to std::function.
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
const char * DispatchFnName
const char * ExecutorSessionObjectName
void addTo(StringMap< ExecutorAddr > &M)
const char * DeregisterEHFrameSectionWrapperName
const char * RegisterEHFrameSectionWrapperName
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
StringMap< ExecutorAddr > BootstrapSymbols
StringMap< std::vector< char > > BootstrapMap