Skip to content

Commit bef55a2

Browse files
committed
[ORC] Introduce EPCGenericRTDyldMemoryManager.
EPCGenericRTDyldMemoryMnaager is an EPC-based implementation of the RuntimeDyld::MemoryManager interface. It enables remote-JITing via EPC (backed by a SimpleExecutorMemoryManager instance on the executor side) for RuntimeDyld clients. The lli and lli-child-target tools are updated to use SimpleRemoteEPC and SimpleRemoteEPCServer (rather than OrcRemoteTargetClient/Server), and EPCGenericRTDyldMemoryManager for MCJIT tests. By enabling remote-JITing for MCJIT and RuntimeDyld-based ORC clients, EPCGenericRTDyldMemoryManager allows us to deprecate older remote-JITing support, including OrcTargetClient/Server, OrcRPCExecutorProcessControl, and the Orc RPC system itself. These will be removed in future patches.
1 parent 18c8ed5 commit bef55a2

File tree

12 files changed

+615
-93
lines changed

12 files changed

+615
-93
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//===---- EPCGenericRTDyldMemoryManager.h - EPC-based MemMgr ----*- C++ -*-===//
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-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Defines a RuntimeDyld::MemoryManager that uses EPC and the ORC runtime
10+
// bootstrap functions.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
15+
#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H
16+
17+
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
18+
#include "llvm/ExecutionEngine/RuntimeDyld.h"
19+
20+
#define DEBUG_TYPE "orc"
21+
22+
namespace llvm {
23+
namespace orc {
24+
25+
/// Remote-mapped RuntimeDyld-compatible memory manager.
26+
class EPCGenericRTDyldMemoryManager : public RuntimeDyld::MemoryManager {
27+
public:
28+
/// Symbol addresses for memory access.
29+
struct SymbolAddrs {
30+
ExecutorAddr Instance;
31+
ExecutorAddr Reserve;
32+
ExecutorAddr Finalize;
33+
ExecutorAddr Deallocate;
34+
ExecutorAddr RegisterEHFrame;
35+
ExecutorAddr DeregisterEHFrame;
36+
};
37+
38+
/// Create an EPCGenericRTDyldMemoryManager using the given EPC, looking up
39+
/// the default symbol names in the bootstrap symbol set.
40+
static Expected<std::unique_ptr<EPCGenericRTDyldMemoryManager>>
41+
CreateWithDefaultBootstrapSymbols(ExecutorProcessControl &EPC);
42+
43+
/// Create an EPCGenericRTDyldMemoryManager using the given EPC and symbol
44+
/// addrs.
45+
EPCGenericRTDyldMemoryManager(ExecutorProcessControl &EPC, SymbolAddrs SAs);
46+
47+
EPCGenericRTDyldMemoryManager(const EPCGenericRTDyldMemoryManager &) = delete;
48+
EPCGenericRTDyldMemoryManager &
49+
operator=(const EPCGenericRTDyldMemoryManager &) = delete;
50+
EPCGenericRTDyldMemoryManager(EPCGenericRTDyldMemoryManager &&) = delete;
51+
EPCGenericRTDyldMemoryManager &
52+
operator=(EPCGenericRTDyldMemoryManager &&) = delete;
53+
~EPCGenericRTDyldMemoryManager();
54+
55+
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
56+
unsigned SectionID,
57+
StringRef SectionName) override;
58+
59+
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
60+
unsigned SectionID, StringRef SectionName,
61+
bool IsReadOnly) override;
62+
63+
void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
64+
uintptr_t RODataSize, uint32_t RODataAlign,
65+
uintptr_t RWDataSize,
66+
uint32_t RWDataAlign) override;
67+
68+
bool needsToReserveAllocationSpace() override;
69+
70+
void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override;
71+
72+
void deregisterEHFrames() override;
73+
74+
void notifyObjectLoaded(RuntimeDyld &Dyld,
75+
const object::ObjectFile &Obj) override;
76+
77+
bool finalizeMemory(std::string *ErrMsg = nullptr) override;
78+
79+
private:
80+
struct Alloc {
81+
public:
82+
Alloc(uint64_t Size, unsigned Align)
83+
: Size(Size), Align(Align),
84+
Contents(std::make_unique<uint8_t[]>(Size + Align - 1)) {}
85+
86+
uint64_t Size;
87+
unsigned Align;
88+
std::unique_ptr<uint8_t[]> Contents;
89+
ExecutorAddr RemoteAddr;
90+
};
91+
92+
struct EHFrame {
93+
ExecutorAddr Addr;
94+
uint64_t Size;
95+
};
96+
97+
// Group of section allocations to be allocated together in the executor. The
98+
// RemoteCodeAddr will stand in as the id of the group for deallocation
99+
// purposes.
100+
struct AllocGroup {
101+
AllocGroup() = default;
102+
AllocGroup(const AllocGroup &) = delete;
103+
AllocGroup &operator=(const AllocGroup &) = delete;
104+
AllocGroup(AllocGroup &&) = default;
105+
AllocGroup &operator=(AllocGroup &&) = default;
106+
107+
ExecutorAddrRange RemoteCode;
108+
ExecutorAddrRange RemoteROData;
109+
ExecutorAddrRange RemoteRWData;
110+
std::vector<EHFrame> UnfinalizedEHFrames;
111+
std::vector<Alloc> CodeAllocs, RODataAllocs, RWDataAllocs;
112+
};
113+
114+
// Maps all allocations in Allocs to aligned blocks
115+
void mapAllocsToRemoteAddrs(RuntimeDyld &Dyld, std::vector<Alloc> &Allocs,
116+
ExecutorAddr NextAddr);
117+
118+
ExecutorProcessControl &EPC;
119+
SymbolAddrs SAs;
120+
121+
std::mutex M;
122+
std::vector<AllocGroup> Unmapped;
123+
std::vector<AllocGroup> Unfinalized;
124+
std::vector<ExecutorAddr> FinalizedAllocs;
125+
std::string ErrMsg;
126+
};
127+
128+
} // end namespace orc
129+
} // end namespace llvm
130+
131+
#undef DEBUG_TYPE
132+
133+
#endif // LLVM_EXECUTIONENGINE_ORC_EPCGENERICRTDYLDMEMORYMANAGER_H

llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ extern const char *MemoryWriteUInt32sWrapperName;
3737
extern const char *MemoryWriteUInt64sWrapperName;
3838
extern const char *MemoryWriteBuffersWrapperName;
3939

40+
extern const char *RegisterEHFrameSectionCustomDirectWrapperName;
41+
extern const char *DeregisterEHFrameSectionCustomDirectWrapperName;
42+
4043
extern const char *RunAsMainWrapperName;
4144

4245
using SPSSimpleExecutorDylibManagerOpenSignature =

llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h

+16
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr,
3333
} // end namespace orc
3434
} // end namespace llvm
3535

36+
/// An eh-frame registration utility suitable for use as a support function
37+
/// call. This function expects the direct address and size of the eh-frame
38+
/// section to register as its arguments (it does not treat its arguments as
39+
/// pointers to an SPS-serialized arg buffer).
40+
extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
41+
llvm_orc_registerEHFrameSectionCustomDirectWrapper(
42+
const char *EHFrameSectionAddr, uint64_t Size);
43+
44+
/// An eh-frame deregistration utility suitable for use as a support function
45+
/// call. This function expects the direct address and size of the eh-frame
46+
/// section to register as its arguments (it does not treat its arguments as
47+
/// pointers to an SPS-serialized arg buffer).
48+
extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
49+
llvm_orc_deregisterEHFrameSectionCustomDirectWrapper(
50+
const char *EHFrameSectionAddr, uint64_t Size);
51+
3652
extern "C" llvm::orc::shared::detail::CWrapperFunctionResult
3753
llvm_orc_registerEHFrameSectionWrapper(const char *Data, uint64_t Size);
3854

llvm/lib/ExecutionEngine/Orc/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_llvm_component_library(LLVMOrcJIT
99
EPCEHFrameRegistrar.cpp
1010
EPCGenericDylibManager.cpp
1111
EPCGenericJITLinkMemoryManager.cpp
12+
EPCGenericRTDyldMemoryManager.cpp
1213
EPCIndirectionUtils.cpp
1314
ExecutionUtils.cpp
1415
IndirectionUtils.cpp

0 commit comments

Comments
 (0)