Skip to content

Commit aa5f257

Browse files
committed
more test updates (deadlocks) and adapt some blocking function to be more explicit
1 parent e3f7ea2 commit aa5f257

27 files changed

+407
-499
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
2121
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
2222
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
23+
#include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
2324
#include "llvm/Support/Allocator.h"
2425
#include "llvm/Support/Compiler.h"
2526
#include "llvm/Support/Error.h"
@@ -34,6 +35,11 @@
3435
#include <mutex>
3536

3637
namespace llvm {
38+
39+
namespace orc {
40+
class ExecutorProcessControl;
41+
}
42+
3743
namespace jitlink {
3844

3945
class Block;
@@ -132,14 +138,15 @@ class LLVM_ABI JITLinkMemoryManager {
132138
/// Called to transfer working memory to the target and apply finalization.
133139
virtual void finalize(OnFinalizedFunction OnFinalized) = 0;
134140

135-
/// Synchronous convenience version of finalize.
136-
Expected<FinalizedAlloc> finalize() {
137-
std::promise<MSVCPExpected<FinalizedAlloc>> FinalizeResultP;
141+
/// Co-synchronous convenience version of finalize.
142+
Expected<FinalizedAlloc> finalize(orc::TaskDispatcher &D) {
143+
orc::promise<MSVCPExpected<FinalizedAlloc>> FinalizeResultP;
138144
auto FinalizeResultF = FinalizeResultP.get_future();
139-
finalize([&](Expected<FinalizedAlloc> Result) {
145+
finalize([FinalizeResultP = std::move(FinalizeResultP)](
146+
Expected<FinalizedAlloc> Result) mutable {
140147
FinalizeResultP.set_value(std::move(Result));
141148
});
142-
return FinalizeResultF.get();
149+
return FinalizeResultF.get(D);
143150
}
144151
};
145152

@@ -163,14 +170,17 @@ class LLVM_ABI JITLinkMemoryManager {
163170
virtual void allocate(const JITLinkDylib *JD, LinkGraph &G,
164171
OnAllocatedFunction OnAllocated) = 0;
165172

166-
/// Convenience function for blocking allocation.
167-
AllocResult allocate(const JITLinkDylib *JD, LinkGraph &G) {
168-
std::promise<MSVCPExpected<std::unique_ptr<InFlightAlloc>>> AllocResultP;
173+
/// Convenience function for co-blocking allocation.
174+
AllocResult allocate(const JITLinkDylib *JD, LinkGraph &G,
175+
orc::TaskDispatcher &D) {
176+
orc::promise<MSVCPExpected<std::unique_ptr<InFlightAlloc>>> AllocResultP;
169177
auto AllocResultF = AllocResultP.get_future();
170-
allocate(JD, G, [&](AllocResult Alloc) {
171-
AllocResultP.set_value(std::move(Alloc));
172-
});
173-
return AllocResultF.get();
178+
allocate(
179+
JD, G,
180+
[AllocResultP = std::move(AllocResultP)](AllocResult Alloc) mutable {
181+
AllocResultP.set_value(std::move(Alloc));
182+
});
183+
return AllocResultF.get(D);
174184
}
175185

176186
/// Deallocate a list of allocation objects.
@@ -187,20 +197,22 @@ class LLVM_ABI JITLinkMemoryManager {
187197
deallocate(std::move(Allocs), std::move(OnDeallocated));
188198
}
189199

190-
/// Convenience function for blocking deallocation.
191-
Error deallocate(std::vector<FinalizedAlloc> Allocs) {
192-
std::promise<MSVCPError> DeallocResultP;
200+
/// Convenience function for co-blocking deallocation.
201+
Error deallocate(std::vector<FinalizedAlloc> Allocs, orc::TaskDispatcher &D) {
202+
orc::promise<MSVCPError> DeallocResultP;
193203
auto DeallocResultF = DeallocResultP.get_future();
194204
deallocate(std::move(Allocs),
195-
[&](Error Err) { DeallocResultP.set_value(std::move(Err)); });
196-
return DeallocResultF.get();
205+
[DeallocResultP = std::move(DeallocResultP)](Error Err) mutable {
206+
DeallocResultP.set_value(std::move(Err));
207+
});
208+
return DeallocResultF.get(D);
197209
}
198210

199-
/// Convenience function for blocking deallocation of a single alloc.
200-
Error deallocate(FinalizedAlloc Alloc) {
211+
/// Convenience function for co-blocking deallocation of a single alloc.
212+
Error deallocate(FinalizedAlloc Alloc, orc::TaskDispatcher &D) {
201213
std::vector<FinalizedAlloc> Allocs;
202214
Allocs.push_back(std::move(Alloc));
203-
return deallocate(std::move(Allocs));
215+
return deallocate(std::move(Allocs), D);
204216
}
205217
};
206218

@@ -326,10 +338,12 @@ class SimpleSegmentAlloc {
326338
Triple TT, const JITLinkDylib *JD,
327339
SegmentMap Segments, OnCreatedFunction OnCreated);
328340

341+
// The blocking version of this should be deprecated, and requires an
342+
// TaskDispatcher for co-async correctness.
329343
LLVM_ABI static Expected<SimpleSegmentAlloc>
330344
Create(JITLinkMemoryManager &MemMgr,
331345
std::shared_ptr<orc::SymbolStringPool> SSP, Triple TT,
332-
const JITLinkDylib *JD, SegmentMap Segments);
346+
const JITLinkDylib *JD, SegmentMap Segments, orc::TaskDispatcher &D);
333347

334348
LLVM_ABI SimpleSegmentAlloc(SimpleSegmentAlloc &&);
335349
LLVM_ABI SimpleSegmentAlloc &operator=(SimpleSegmentAlloc &&);
@@ -343,9 +357,10 @@ class SimpleSegmentAlloc {
343357
Alloc->finalize(std::move(OnFinalized));
344358
}
345359

346-
/// Finalize all groups.
347-
Expected<JITLinkMemoryManager::FinalizedAlloc> finalize() {
348-
return Alloc->finalize();
360+
/// Finalize all groups (deprecated co-blocking version).
361+
Expected<JITLinkMemoryManager::FinalizedAlloc>
362+
finalize(orc::TaskDispatcher &D) {
363+
return Alloc->finalize(D);
349364
}
350365

351366
private:

llvm/include/llvm/ExecutionEngine/Orc/DylibManager.h

Lines changed: 1 addition & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_EXECUTIONENGINE_ORC_DYLIBMANAGER_H
1515

1616
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
17+
#include "llvm/ExecutionEngine/Orc/InProcessMemoryAccess.h"
1718
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
1819
#include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
1920
#include "llvm/Support/Compiler.h"
@@ -75,104 +76,7 @@ class LLVM_ABI DylibManager : public ExecutorProcessControl {
7576
SymbolLookupCompleteFn F) = 0;
7677
};
7778

78-
/// A ExecutorProcessControl instance that asserts if any of its methods are
79-
/// used. Suitable for use is unit tests, and by ORC clients who haven't moved
80-
/// to ExecutorProcessControl-based APIs yet.
81-
class UnsupportedExecutorProcessControl : public DylibManager,
82-
private InProcessMemoryAccess {
83-
public:
84-
UnsupportedExecutorProcessControl(
85-
std::shared_ptr<SymbolStringPool> SSP = nullptr,
86-
std::unique_ptr<TaskDispatcher> D = nullptr, const std::string &TT = "",
87-
unsigned PageSize = 0)
88-
: DylibManager(
89-
SSP ? std::move(SSP) : std::make_shared<SymbolStringPool>(),
90-
D ? std::move(D) : std::make_unique<InPlaceTaskDispatcher>()),
91-
InProcessMemoryAccess(*this, Triple(TT).isArch64Bit()) {
92-
this->TargetTriple = Triple(TT);
93-
this->PageSize = PageSize;
94-
this->MemAccess = this;
95-
}
96-
97-
Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr,
98-
ArrayRef<std::string> Args) override {
99-
llvm_unreachable("Unsupported");
100-
}
101-
102-
Expected<int32_t> runAsVoidFunction(ExecutorAddr VoidFnAddr) override {
103-
llvm_unreachable("Unsupported");
104-
}
105-
106-
Expected<int32_t> runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override {
107-
llvm_unreachable("Unsupported");
108-
}
109-
110-
void callWrapperAsync(ExecutorAddr WrapperFnAddr,
111-
IncomingWFRHandler OnComplete,
112-
ArrayRef<char> ArgBuffer) override {
113-
llvm_unreachable("Unsupported");
114-
}
115-
116-
Error disconnect() override { return Error::success(); }
117-
118-
Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override {
119-
return make_error<StringError>("Unsupported", inconvertibleErrorCode());
120-
}
121-
122-
void lookupSymbolsAsync(ArrayRef<LookupRequest> Request,
123-
SymbolLookupCompleteFn F) override {
124-
F(make_error<StringError>("Unsupported", inconvertibleErrorCode()));
125-
}
126-
};
127-
128-
/// A ExecutorProcessControl implementation targeting the current process.
129-
class LLVM_ABI SelfExecutorProcessControl : public DylibManager,
130-
private InProcessMemoryAccess {
131-
public:
132-
SelfExecutorProcessControl(
133-
std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
134-
Triple TargetTriple, unsigned PageSize,
135-
std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
136-
137-
/// Create a SelfExecutorProcessControl with the given symbol string pool and
138-
/// memory manager.
139-
/// If no symbol string pool is given then one will be created.
140-
/// If no memory manager is given a jitlink::InProcessMemoryManager will
141-
/// be created and used by default.
142-
static Expected<std::unique_ptr<SelfExecutorProcessControl>>
143-
Create(std::shared_ptr<SymbolStringPool> SSP = nullptr,
144-
std::unique_ptr<TaskDispatcher> D = nullptr,
145-
std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr = nullptr);
146-
147-
Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr,
148-
ArrayRef<std::string> Args) override;
149-
150-
Expected<int32_t> runAsVoidFunction(ExecutorAddr VoidFnAddr) override;
15179

152-
Expected<int32_t> runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override;
153-
154-
void callWrapperAsync(ExecutorAddr WrapperFnAddr,
155-
IncomingWFRHandler OnComplete,
156-
ArrayRef<char> ArgBuffer) override;
157-
158-
Error disconnect() override;
159-
160-
private:
161-
static shared::CWrapperFunctionResult
162-
jitDispatchViaWrapperFunctionManager(void *Ctx, const void *FnTag,
163-
const char *Data, size_t Size);
164-
165-
Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
166-
167-
void lookupSymbolsAsync(ArrayRef<LookupRequest> Request,
168-
SymbolLookupCompleteFn F) override;
169-
170-
std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
171-
#ifdef __APPLE__
172-
std::unique_ptr<UnwindInfoManager> UnwindInfoMgr;
173-
#endif // __APPLE__
174-
char GlobalManglingPrefix = 0;
175-
};
17680

17781
} // end namespace llvm::orc
17882

llvm/include/llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// Implements ExecutorProcessControl::MemoryAccess by making calls to
9+
// Implements MemoryAccess by making calls to
1010
// ExecutorProcessControl::callWrapperAsync.
1111
//
1212
// This simplifies the implementaton of new ExecutorProcessControl instances,
@@ -19,6 +19,7 @@
1919
#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICMEMORYACCESS_H
2020

2121
#include "llvm/ExecutionEngine/Orc/Core.h"
22+
#include "llvm/ExecutionEngine/Orc/MemoryAccess.h"
2223

2324
namespace llvm {
2425
namespace orc {
@@ -107,8 +108,7 @@ class EPCGenericMemoryAccess : public MemoryAccess {
107108
void readUInt16sAsync(ArrayRef<ExecutorAddr> Rs,
108109
OnReadUIntsCompleteFn<uint16_t> OnComplete) override {
109110
using namespace shared;
110-
EPC.callSPSWrapperAsync<SPSSequence<uint16_t>(
111-
SPSSequence<SPSExecutorAddr>)>(
111+
EPC.callSPSWrapperAsync<SPSSequence<uint16_t>(SPSSequence<SPSExecutorAddr>)>(
112112
FAs.ReadUInt16s,
113113
[OnComplete = std::move(OnComplete)](
114114
Error Err, ReadUIntsResult<uint16_t> Result) mutable {
@@ -123,8 +123,7 @@ class EPCGenericMemoryAccess : public MemoryAccess {
123123
void readUInt32sAsync(ArrayRef<ExecutorAddr> Rs,
124124
OnReadUIntsCompleteFn<uint32_t> OnComplete) override {
125125
using namespace shared;
126-
EPC.callSPSWrapperAsync<SPSSequence<uint32_t>(
127-
SPSSequence<SPSExecutorAddr>)>(
126+
EPC.callSPSWrapperAsync<SPSSequence<uint32_t>(SPSSequence<SPSExecutorAddr>)>(
128127
FAs.ReadUInt32s,
129128
[OnComplete = std::move(OnComplete)](
130129
Error Err, ReadUIntsResult<uint32_t> Result) mutable {
@@ -139,8 +138,7 @@ class EPCGenericMemoryAccess : public MemoryAccess {
139138
void readUInt64sAsync(ArrayRef<ExecutorAddr> Rs,
140139
OnReadUIntsCompleteFn<uint64_t> OnComplete) override {
141140
using namespace shared;
142-
EPC.callSPSWrapperAsync<SPSSequence<uint64_t>(
143-
SPSSequence<SPSExecutorAddr>)>(
141+
EPC.callSPSWrapperAsync<SPSSequence<uint64_t>(SPSSequence<SPSExecutorAddr>)>(
144142
FAs.ReadUInt64s,
145143
[OnComplete = std::move(OnComplete)](
146144
Error Err, ReadUIntsResult<uint64_t> Result) mutable {

0 commit comments

Comments
 (0)