LLVM: lib/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

17

19

20#define DEBUG_TYPE "orc"

21

23

24namespace llvm {

25namespace orc {

26

28

30

31#if LLVM_ENABLE_THREADS

32void SimpleRemoteEPCServer::ThreadDispatcher::dispatch(

34 {

35 std::lock_guardstd::mutex Lock(DispatchMutex);

36 if (!Running)

37 return;

38 ++Outstanding;

39 }

40

41 std::thread([this, Work = std::move(Work)]() mutable {

42 Work();

43 std::lock_guardstd::mutex Lock(DispatchMutex);

44 --Outstanding;

45 OutstandingCV.notify_all();

46 }).detach();

47}

48

49void SimpleRemoteEPCServer::ThreadDispatcher::shutdown() {

50 std::unique_lockstd::mutex Lock(DispatchMutex);

51 Running = false;

52 OutstandingCV.wait(Lock, [this]() { return Outstanding == 0; });

53}

54#endif

55

61

66

68 dbgs() << "SimpleRemoteEPCServer::handleMessage: opc = ";

69 switch (OpC) {

71 dbgs() << "Setup";

72 assert(SeqNo == 0 && "Non-zero SeqNo for Setup?");

73 assert(!TagAddr && "Non-zero TagAddr for Setup?");

74 break;

76 dbgs() << "Hangup";

77 assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");

78 assert(!TagAddr && "Non-zero TagAddr for Hangup?");

79 break;

81 dbgs() << "Result";

82 assert(!TagAddr && "Non-zero TagAddr for Result?");

83 break;

85 dbgs() << "CallWrapper";

86 break;

87 }

88 dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr

89 << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())

90 << " bytes\n";

91 });

92

93 using UT = std::underlying_type_t;

97

98

99 switch (OpC) {

106 if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))

107 return std::move(Err);

108 break;

110 handleCallWrapper(SeqNo, TagAddr, std::move(ArgBytes));

111 break;

112 }

114}

115

117 std::unique_lockstd::mutex Lock(ServerStateMutex);

118 ShutdownCV.wait(Lock, [this]() { return RunState == ServerShutDown; });

119 return std::move(ShutdownErr);

120}

121

123 PendingJITDispatchResultsMap TmpPending;

124

125 {

126 std::lock_guardstd::mutex Lock(ServerStateMutex);

127 std::swap(TmpPending, PendingJITDispatchResults);

128 RunState = ServerShuttingDown;

129 }

130

131

132 for (auto &KV : TmpPending)

133 KV.second->set_value(

135

136

137 D->shutdown();

138

139

140 while (!Services.empty()) {

141 ShutdownErr =

142 joinErrors(std::move(ShutdownErr), Services.back()->shutdown());

143 Services.pop_back();

144 }

145

146 std::lock_guardstd::mutex Lock(ServerStateMutex);

147 ShutdownErr = joinErrors(std::move(ShutdownErr), std::move(Err));

148 RunState = ServerShutDown;

149 ShutdownCV.notify_all();

150}

151

155

157 dbgs() << "SimpleRemoteEPCServer::sendMessage: opc = ";

158 switch (OpC) {

160 dbgs() << "Setup";

161 assert(SeqNo == 0 && "Non-zero SeqNo for Setup?");

162 assert(!TagAddr && "Non-zero TagAddr for Setup?");

163 break;

165 dbgs() << "Hangup";

166 assert(SeqNo == 0 && "Non-zero SeqNo for Hangup?");

167 assert(!TagAddr && "Non-zero TagAddr for Hangup?");

168 break;

170 dbgs() << "Result";

171 assert(!TagAddr && "Non-zero TagAddr for Result?");

172 break;

174 dbgs() << "CallWrapper";

175 break;

176 }

177 dbgs() << ", seqno = " << SeqNo << ", tag-addr = " << TagAddr

178 << ", arg-buffer = " << formatv("{0:x}", ArgBytes.size())

179 << " bytes\n";

180 });

181 auto Err = T->sendMessage(OpC, SeqNo, TagAddr, ArgBytes);

183 if (Err)

184 dbgs() << " \\--> SimpleRemoteEPC::sendMessage failed\n";

185 });

186 return Err;

187}

188

189Error SimpleRemoteEPCServer::sendSetupMessage(

190 StringMap<std::vector> BootstrapMap,

191 StringMap BootstrapSymbols) {

192

193 using namespace SimpleRemoteEPCDefaultBootstrapSymbolNames;

194

195 SimpleRemoteEPCExecutorInfo EI;

199 else

203

205 "Dispatch context name should not be set");

207 "Dispatch function name should not be set");

211

212 using SPSSerialize =

213 shared::SPSArgListshared::SPSSimpleRemoteEPCExecutorInfo;

214 auto SetupPacketBytes =

216 shared::SPSOutputBuffer OB(SetupPacketBytes.data(), SetupPacketBytes.size());

217 if (!SPSSerialize::serialize(OB, EI))

220

222 {SetupPacketBytes.data(), SetupPacketBytes.size()});

223}

224

225Error SimpleRemoteEPCServer::handleResult(

228 std::promiseshared::WrapperFunctionResult *P = nullptr;

229 {

230 std::lock_guardstd::mutex Lock(ServerStateMutex);

231 auto I = PendingJITDispatchResults.find(SeqNo);

232 if (I == PendingJITDispatchResults.end())

234 Twine(SeqNo),

236 P = I->second;

237 PendingJITDispatchResults.erase(I);

238 releaseSeqNo(SeqNo);

239 }

241 memcpy(R.data(), ArgBytes.data(), ArgBytes.size());

242 P->set_value(std::move(R));

244}

245

246void SimpleRemoteEPCServer::handleCallWrapper(

249 D->dispatch([this, RemoteSeqNo, TagAddr, ArgBytes = std::move(ArgBytes)]() {

250 using WrapperFnTy =

251 shared::CWrapperFunctionResult (*)(const char *, size_t);

252 auto *Fn = TagAddr.toPtr();

253 shared::WrapperFunctionResult ResultBytes(

254 Fn(ArgBytes.data(), ArgBytes.size()));

256 ExecutorAddr(),

257 {ResultBytes.data(), ResultBytes.size()}))

258 ReportError(std::move(Err));

259 });

260}

261

263SimpleRemoteEPCServer::doJITDispatch(const void *FnTag, const char *ArgData,

264 size_t ArgSize) {

265 uint64_t SeqNo;

266 std::promiseshared::WrapperFunctionResult ResultP;

267 auto ResultF = ResultP.get_future();

268 {

269 std::lock_guardstd::mutex Lock(ServerStateMutex);

270 if (RunState != ServerRunning)

272 "jit_dispatch not available (EPC server shut down)");

273

274 SeqNo = getNextSeqNo();

275 assert(!PendingJITDispatchResults.count(SeqNo) && "SeqNo already in use");

276 PendingJITDispatchResults[SeqNo] = &ResultP;

277 }

278

281 ReportError(std::move(Err));

282

283 return ResultF.get();

284}

285

287SimpleRemoteEPCServer::jitDispatchEntry(void *DispatchCtx, const void *FnTag,

288 const char *ArgData, size_t ArgSize) {

289 return reinterpret_cast<SimpleRemoteEPCServer *>(DispatchCtx)

290 ->doJITDispatch(FnTag, ArgData, ArgSize)

291 .release();

292}

293

294}

295}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

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 ...

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

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().

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

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()

static StringMap< ExecutorAddr > defaultBootstrapSymbols()

Definition SimpleRemoteEPCServer.cpp:56

Expected< HandleMessageAction > handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes) override

Call to handle an incoming message.

Definition SimpleRemoteEPCServer.cpp:63

void handleDisconnect(Error Err) override

Handle a disconnection from the underlying transport.

Definition SimpleRemoteEPCServer.cpp:122

Error waitForDisconnect()

Definition SimpleRemoteEPCServer.cpp:116

static LLVM_ABI 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.

LLVM_ABI const char * DispatchFnName

LLVM_ABI const char * ExecutorSessionObjectName

void addTo(StringMap< ExecutorAddr > &M)

LLVM_ABI void addDefaultBootstrapValuesForHostProcess(StringMap< std::vector< char > > &BootstrapMap, StringMap< ExecutorAddr > &BootstrapSymbols)

SmallVector< char, 128 > SimpleRemoteEPCArgBytesVector

LLVM_ABI 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.

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)

Error joinErrors(Error E1, Error E2)

Concatenate errors.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

StringMap< ExecutorAddr > BootstrapSymbols

StringMap< std::vector< char > > BootstrapMap