Skip to content

Commit f725ece

Browse files
lhamesgithub-actions[bot]
authored andcommitted
Automerge: [orc-rt] Initial ORC Runtime design documentation. (#168681)
This document aims to lay out the high level design and goals of the ORC runtime, and the relationships between key components.
2 parents 4f4b260 + de9c182 commit f725ece

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

orc-rt/docs/Design.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# ORC Runtime Design
2+
3+
The ORC runtime provides APIs for *executor* processes in an ORC JIT session
4+
(as opposed to the LLVM ORC libraries which provide APIs for *controller*
5+
processes). This includes support for both JIT'd code itself, and for users
6+
of JIT'd code.
7+
8+
## Background
9+
10+
LLVM's On Request Compilation (ORC) APIs support cross-process loading of JIT'd
11+
code. We call the process that defines and links the JIT'd code the *controller*
12+
and the process that executes JIT'd code the *executor*. Controller processes
13+
will link LLVM's ORC library, and construct a JIT'd program using an
14+
llvm::orc::ExecutionSession instance (typically through an convenience wrapper
15+
like llvm::orc::LLJIT). Executor processes construct an `orc_rt::Session`
16+
object to manage resources for, and access to, JIT'd code within the executor
17+
process.
18+
19+
## APIs
20+
21+
### Session
22+
23+
The Session object is the root object for a JIT'd program. It owns the
24+
ResourceManager instances that manage resources supporting JIT'd code (e.g.
25+
JIT'd memory, unwind info registrations, dynamic library handles, etc.).
26+
27+
The Session object must be constructed prior to adding any JIT'd code, and must
28+
outlive execution of any JIT'd code.
29+
30+
An executor may have more than one Session object, in which case each Session
31+
object must outlive execution of any JIT'd code added to that specific session.
32+
33+
### ControllerAccess
34+
35+
ControllerAccess objects support bidirectional RPC between JIT'd code in the
36+
executor and the ExecutionSession in the controller.
37+
38+
Calls in both directions are to "wrapper functions" with a fixed signature (a
39+
function that takes a blob of bytes and returns a blob of bytes as its result).
40+
ControllerAccess objects can not generally assume anything about the format of
41+
the bytes being sent (their interpretation is up to the called function). The
42+
RPC is not fully symmetric: Calls from the controller to the executor specify
43+
wrapper function *addresses* (i.e. the controller can invoke any code in the
44+
executor). Calls from the executor to the controller specify *tags*, which are
45+
addresses in the executor processes that are associated with handlers in the
46+
controller. This ensures that the executing process can only call deliberately
47+
exposed entry points in the controller.
48+
49+
ControllerAccess objects may be detached before the session ends, at which point
50+
JIT'd code may continue executing, but will receive no further calls from the
51+
controller and can make no further calls to the controller.
52+
53+
### ResourceManager
54+
55+
`ResourceManager` is an interface for classes that manage resources that support
56+
a JIT'd program, for example memory or loaded dylib handles. It provides two
57+
operations: `detach` and `shutdown`. The `shutdown` operation will be called at
58+
`Session` destruction time. The `detach` operation may be called if the
59+
controller detaches: since this means that no further requests for resource
60+
allocation or release will occur prior to the end of the Session
61+
ResourceManagers may implement this operation to abandon any fine-grained
62+
tracking or pre-reserved resources (e.g. address space).
63+
64+
### TaskDispatcher
65+
66+
Runs Tasks within the ORC runtime. In particular, calls originating from the
67+
controller (via ControllerAccess) will be dispatched as Tasks.
68+
69+
TaskDispatchers are responsible for ensuring that all dispatched Tasks have
70+
completed or been destroyed during Session shutdown.
71+
72+
### WrapperFunction
73+
74+
A wrapper function is any function with the following C signature:
75+
76+
```c
77+
void (orc_rt_SessionRef Session, uint64_t CallId,
78+
orc_rt_WrapperFunctionReturn Return,
79+
orc_rt_WrapperFunctionBuffer ArgBytes);
80+
```
81+
82+
where `orc_rt_WrapperFunctionReturn` and `orc_rt_WrapperFunctionBuffer` are
83+
defined as:
84+
85+
```c
86+
typedef struct {
87+
orc_rt_WrapperFunctionBufferDataUnion Data;
88+
size_t Size;
89+
} orc_rt_WrapperFunctionBuffer;
90+
91+
/**
92+
* Asynchronous return function for an orc-rt wrapper function.
93+
*/
94+
typedef void (*orc_rt_WrapperFunctionReturn)(
95+
orc_rt_SessionRef Session, uint64_t CallId,
96+
orc_rt_WrapperFunctionBuffer ResultBytes);
97+
```
98+
99+
The orc_rt::WrapperFunction class provides APIs for implementing and calling
100+
wrapper functions.
101+
102+
### SPSWrapperFunction
103+
104+
An SPS wrapper function is a wrapper function that uses the
105+
SimplePackedSerialization scheme (see documentation in
106+
orc-rt/include/orc-rt/SimplePackedSerialization.h).
107+
108+
## TODO:
109+
110+
Document...
111+
112+
* C API
113+
* Error handling
114+
* RTTI
115+
* ExecutorAddr / ExecutorAddrRange
116+
* SimpleNativeMemoryMap
117+
* Memory Access (unimplemented)
118+
* Platform classes (unimplemented)
119+
* Other utilities

0 commit comments

Comments
 (0)