1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*
* jit-context.c - Functions for manipulating JIT contexts.
*
* Copyright (C) 2004 Southern Storm Software, Pty Ltd.
*
* This file is part of the libjit library.
*
* The libjit library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 2.1 of
* the License, or (at your option) any later version.
*
* The libjit library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the libjit library. If not, see
* <http://www.gnu.org/licenses/>.
*/
/*@
Everything that is done with @code{libjit} is done relative to a context.
It is possible to have more than one context at a time - each acts as an
independent environment for compiling and managing code.
When you want to compile a function, you create it with
@code{jit_function_create}, and then populate its body with
calls to the value and instruction functions. See @xref{Values}, and
@ref{Instructions} for more information on how to do this.
@section Using libjit in a multi-threaded environment
The library does not handle the creation, management, and destruction
of threads itself. It is up to the front-end environment to take
care of that. But the library is thread-aware, as long as you take
some very simple steps.
In a multi-threaded environment, you must ensure that only one
thread can build functions at any one time. Otherwise the
JIT's context may become corrupted. To protect the system,
you should call @code{jit_context_build_start} before
creating the function. And then call @code{jit_context_build_end}
once the function has been fully compiled.
You can compile multiple functions during the one build process
if you wish, which is the normal case when compiling a class.
It is usually a good idea to suspend the finalization of
garbage-collected objects while function building is in progress.
Otherwise you may get a deadlock when the finalizer thread tries
to call the builder to compile a finalization routine. Suspension
of finalization is the responsibility of the caller.
@section Context functions
@cindex jit-context.h
The following functions are available to create, manage, and
ultimately destroy JIT contexts:
@*/
/*@
* @deftypefun jit_context_t jit_context_create (void)
* Create a new context block for the JIT. Returns NULL
* if out of memory.
* @end deftypefun
@*/
jit_context_t
/*@
* @deftypefun void jit_context_destroy (jit_context_t @var{context})
* Destroy a JIT context block and everything that is associated with it.
* It is very important that no threads within the program are currently
* running compiled code when this function is called.
* @end deftypefun
@*/
void
/*@
* @deftypefun void jit_context_build_start (jit_context_t @var{context})
* This routine should be called before you start building a function
* to be JIT'ed. It acquires a lock on the context to prevent other
* threads from accessing the build process, since only one thread
* can be performing build operations at any one time.
* @end deftypefun
@*/
void
/*@
* @deftypefun void jit_context_build_end (jit_context_t @var{context})
* This routine should be called once you have finished building
* and compiling a function and are ready to resume normal execution.
* This routine will release the build lock, allowing other threads
* that are waiting on the builder to proceed.
* @end deftypefun
@*/
void
/*@
* @deftypefun void jit_context_set_on_demand_driver (jit_context_t @var{context}, jit_on_demand_driver_func @var{driver})
* Specify the C function to be called to drive on-demand compilation.
*
* When on-demand compilation is requested the default driver provided by
* @code{libjit} takes the following actions:
*
* @enumerate
* @item
* The context is locked by calling @code{jit_context_build_start}.
*
* @item
* If the function has already been compiled, @code{libjit} unlocks
* the context and returns immediately. This can happen because of race
* conditions between threads: some other thread may have beaten us
* to the on-demand compiler.
*
* @item
* The user's on-demand compiler is called. It is responsible for building
* the instructions in the function's body. It should return one of the
* result codes @code{JIT_RESULT_OK}, @code{JIT_RESULT_COMPILE_ERROR},
* or @code{JIT_RESULT_OUT_OF_MEMORY}.
*
* @item
* If the user's on-demand function hasn't already done so, @code{libjit}
* will call @code{jit_function_compile} to compile the function.
*
* @item
* The context is unlocked by calling @code{jit_context_build_end} and
* @code{libjit} jumps to the newly-compiled entry point. If an error
* occurs, a built-in exception of type @code{JIT_RESULT_COMPILE_ERROR}
* or @code{JIT_RESULT_OUT_OF_MEMORY} will be thrown.
*
* @item
* The entry point of the compiled function is returned from the driver.
* @end enumerate
*
* You may need to provide your own driver if some additional actions
* are required.
*
* @end deftypefun
@*/
void
/*@
* @deftypefun void jit_context_set_memory_manager (jit_context_t @var{context}, jit_memory_manager_t @var{manager})
* Specify the memory manager plug-in.
* @end deftypefun
@*/
void
/*@
* @deftypefun int jit_context_set_meta (jit_context_t @var{context}, int @var{type}, void *@var{data}, jit_meta_free_func @var{free_data})
* Tag a context with some metadata. Returns zero if out of memory.
*
* Metadata may be used to store dependency graphs, branch prediction
* information, or any other information that is useful to optimizers
* or code generators. It can also be used by higher level user code
* to store information about the context that is specific to the
* virtual machine or language.
*
* If the @var{type} already has some metadata associated with it, then
* the previous value will be freed.
* @end deftypefun
@*/
int
/*@
* @deftypefun int jit_context_set_meta_numeric (jit_context_t @var{context}, int @var{type}, jit_nuint @var{data})
* Tag a context with numeric metadata. Returns zero if out of memory.
* This function is more convenient for accessing the context's
* special option values:
*
* @table @code
* @vindex JIT_OPTION_CACHE_LIMIT
* @item JIT_OPTION_CACHE_LIMIT
* A numeric option that indicates the maximum size in bytes of the function
* cache. If set to zero (the default), the function cache is unlimited
* in size.
*
* @vindex JIT_OPTION_CACHE_PAGE_SIZE
* @item JIT_OPTION_CACHE_PAGE_SIZE
* A numeric option that indicates the size in bytes of a single page in the
* function cache. Memory is allocated for the cache in chunks of
* this size. If set to zero, the cache page size is set to an
* internally-determined default (usually 128k). The cache page size
* also determines the maximum size of a single compiled function.
*
* @vindex JIT_OPTION_PRE_COMPILE
* @item JIT_OPTION_PRE_COMPILE
* A numeric option that indicates that this context is being used
* for pre-compilation if it is set to a non-zero value. Code within
* pre-compiled contexts cannot be executed directly. Instead, they
* can be written out to disk in ELF format to be reloaded at
* some future time.
*
* @vindex JIT_OPTION_DONT_FOLD
* @item JIT_OPTION_DONT_FOLD
* A numeric option that disables constant folding when it is set to a
* non-zero value. This is useful for debugging, as it forces @code{libjit} to
* always execute constant expressions at run time, instead of at compile time.
*
* @vindex JIT_OPTION_POSITION_INDEPENDENT
* @item JIT_OPTION_POSITION_INDEPENDENT
* A numeric option that forces generation of position-independent code (PIC)
* if it is set to a non-zero value. This may be mainly useful for pre-compiled
* contexts.
* @end table
*
* Metadata type values of 10000 or greater are reserved for internal use.
* @end deftypefun
@*/
int
/*@
* @deftypefun {void *} jit_context_get_meta (jit_context_t @var{context}, int @var{type})
* Get the metadata associated with a particular tag. Returns NULL
* if @var{type} does not have any metadata associated with it.
* @end deftypefun
@*/
void *
/*@
* @deftypefun jit_nuint jit_context_get_meta_numeric (jit_context_t @var{context}, int @var{type})
* Get the metadata associated with a particular tag. Returns zero
* if @var{type} does not have any metadata associated with it.
* This version is more convenient for the pre-defined numeric option values.
* @end deftypefun
@*/
jit_nuint
/*@
* @deftypefun void jit_context_free_meta (jit_context_t @var{context}, int @var{type})
* Free metadata of a specific type on a context. Does nothing if
* the @var{type} does not have any metadata associated with it.
* @end deftypefun
@*/
void