Skip to content

Commit f8c390f

Browse files
committed
JIT: Add flushing of stream and backend
Signed-off-by: Paul Guyot <pguyot@kallisys.net>
1 parent 069e576 commit f8c390f

File tree

8 files changed

+99
-16
lines changed

8 files changed

+99
-16
lines changed

libs/estdlib/src/code_server.erl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ load(Module) ->
164164
code_server:literal_resolver(Module, Index)
165165
end,
166166
TypeResolver = fun(Index) -> code_server:type_resolver(Module, Index) end,
167-
Stream0 = jit:stream(jit_mmap_size(byte_size(Code))),
168-
{BackendModule, BackendState0} = jit:backend(Stream0),
167+
{StreamModule, Stream0} = jit:stream(jit_mmap_size(byte_size(Code))),
168+
{BackendModule, BackendState0} = jit:backend(StreamModule, Stream0),
169169
{LabelsCount, BackendState1} = jit:compile(
170170
Code,
171171
AtomResolver,
@@ -174,12 +174,12 @@ load(Module) ->
174174
BackendModule,
175175
BackendState0
176176
),
177-
BackendState2 = BackendModule:flush(BackendState1),
178-
Stream1 = BackendModule:stream(BackendState2),
179-
code_server:set_native_code(Module, LabelsCount, Stream1),
177+
Stream1 = BackendModule:stream(BackendState1),
178+
Stream2 = StreamModule:flush(Stream1),
179+
code_server:set_native_code(Module, LabelsCount, Stream2),
180180
End = erlang:system_time(millisecond),
181181
io:format("~B ms (bytecode: ~B bytes, native code: ~B bytes)\n", [
182-
End - Start, byte_size(Code), BackendModule:offset(BackendState2)
182+
End - Start, byte_size(Code), BackendModule:offset(BackendState1)
183183
])
184184
catch
185185
T:V:S ->

libs/jit/src/jit.erl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
-export([
2424
stream/1,
25-
backend/1,
25+
backend/2,
2626
beam_chunk_header/3,
2727
compile/6
2828
]).
@@ -148,7 +148,8 @@ compile(
148148
},
149149
{State1, MSt2} = first_pass(Opcodes, MMod, MSt1, State0),
150150
MSt3 = second_pass(MMod, MSt2, State1),
151-
{LabelsCount, MSt3};
151+
MSt4 = MMod:flush(MSt3),
152+
{LabelsCount, MSt4};
152153
compile(
153154
<<16:32, 0:32, OpcodeMax:32, _LabelsCount:32, _FunctionsCount:32, _Opcodes/binary>>,
154155
_AtomResolver,
@@ -3792,7 +3793,7 @@ variant() ->
37923793

37933794
%% @doc Instantiate backend for this platform
37943795
%% @return A tuple with the backend module and the backend state for this platform
3795-
backend({StreamModule, Stream}) ->
3796+
backend(StreamModule, Stream) ->
37963797
BackendModule = ?MODULE:backend_module(),
37973798
Variant = ?MODULE:variant(),
37983799
BackendState = BackendModule:new(Variant, StreamModule, Stream),

libs/jit/src/jit_aarch64.erl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
new/3,
2626
stream/1,
2727
offset/1,
28+
flush/1,
2829
debugger/1,
2930
used_regs/1,
3031
available_regs/1,
@@ -259,6 +260,16 @@ stream(#state{stream = Stream}) ->
259260
offset(#state{stream_module = StreamModule, stream = Stream}) ->
260261
StreamModule:offset(Stream).
261262

263+
%%-----------------------------------------------------------------------------
264+
%% @doc Flush the current state (unused on aarch64)
265+
%% @end
266+
%% @param State current backend state
267+
%% @return The flushed state
268+
%%-----------------------------------------------------------------------------
269+
-spec flush(state()) -> state().
270+
flush(#state{} = State) ->
271+
State.
272+
262273
%%-----------------------------------------------------------------------------
263274
%% @doc Emit a debugger of breakpoint instruction. This is used for debugging
264275
%% and not in production.

libs/jit/src/jit_armv6m.erl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
new/3,
2626
stream/1,
2727
offset/1,
28+
flush/1,
2829
debugger/1,
2930
used_regs/1,
3031
available_regs/1,
@@ -272,6 +273,16 @@ stream(#state{stream = Stream}) ->
272273
offset(#state{stream_module = StreamModule, stream = Stream}) ->
273274
StreamModule:offset(Stream).
274275

276+
%%-----------------------------------------------------------------------------
277+
%% @doc Flush the current state, e.g. literal pools
278+
%% @end
279+
%% @param State current backend state
280+
%% @return The flushed state
281+
%%-----------------------------------------------------------------------------
282+
-spec flush(state()) -> state().
283+
flush(#state{} = State) ->
284+
flush_literal_pool(State).
285+
275286
%%-----------------------------------------------------------------------------
276287
%% @doc Emit a debugger of breakpoint instruction. This is used for debugging
277288
%% and not in production.

libs/jit/src/jit_stream_binary.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
offset/1,
2828
append/2,
2929
replace/3,
30-
map/4
30+
map/4,
31+
flush/1
3132
]).
3233

3334
-export_type([stream/0]).
@@ -93,3 +94,14 @@ map(Stream, Offset, Length, MapFunction) ->
9394
{Prefix, <<Previous:Length/binary, Suffix/binary>>} = split_binary(Stream, Offset),
9495
Replacement = MapFunction(Previous),
9596
<<Prefix/binary, Replacement/binary, Suffix/binary>>.
97+
98+
%%-----------------------------------------------------------------------------
99+
%% @param Stream stream to flush
100+
%% @returns The stream flushed
101+
%% @doc Flush the stream. NOP with binaries.
102+
%%
103+
%% @end
104+
%%-----------------------------------------------------------------------------
105+
-spec flush(stream()) -> stream().
106+
flush(Stream) ->
107+
Stream.

libs/jit/src/jit_stream_mmap.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
offset/1,
2828
append/2,
2929
replace/3,
30-
map/4
30+
map/4,
31+
flush/1
3132
]).
3233

3334
%% Additional nif
@@ -109,3 +110,14 @@ map(Stream, Offset, Length, MapFunction) ->
109110
-spec read(stream(), non_neg_integer(), pos_integer()) -> binary().
110111
read(_Stream, _Offset, _Length) ->
111112
erlang:nif_error(undefined).
113+
114+
%%-----------------------------------------------------------------------------
115+
%% @param Stream stream to flush
116+
%% @returns The stream flushed
117+
%% @doc Flush the stream. Typically invalidates instruction cache.
118+
%%
119+
%% @end
120+
%%-----------------------------------------------------------------------------
121+
-spec flush(stream()) -> stream().
122+
flush(_Stream) ->
123+
erlang:nif_error(undefined).

libs/jit/src/jit_x86_64.erl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
new/3,
2626
stream/1,
2727
offset/1,
28+
flush/1,
2829
debugger/1,
2930
used_regs/1,
3031
available_regs/1,
@@ -244,6 +245,16 @@ stream(#state{stream = Stream}) ->
244245
offset(#state{stream_module = StreamModule, stream = Stream}) ->
245246
StreamModule:offset(Stream).
246247

248+
%%-----------------------------------------------------------------------------
249+
%% @doc Flush the current state (unused on x86-64)
250+
%% @end
251+
%% @param State current backend state
252+
%% @return The flushed state
253+
%%-----------------------------------------------------------------------------
254+
-spec flush(state()) -> state().
255+
flush(#state{} = State) ->
256+
State.
257+
247258
%%-----------------------------------------------------------------------------
248259
%% @doc Emit a debugger of breakpoint instruction. This is used for debugging
249260
%% and not in production.

src/platforms/generic_unix/lib/jit_stream_mmap.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,28 @@ static term nif_jit_stream_mmap_read(Context *ctx, int argc, term argv[])
193193
return term_from_literal_binary(js_obj->stream_base + offset, len, &ctx->heap, ctx->global);
194194
}
195195

196+
static term nif_jit_stream_mmap_flush(Context *ctx, int argc, term argv[])
197+
{
198+
UNUSED(argc);
199+
200+
void *js_obj_ptr;
201+
if (UNLIKELY(!enif_get_resource(erl_nif_env_from_context(ctx), argv[0], jit_stream_mmap_resource_type, &js_obj_ptr))) {
202+
RAISE_ERROR(BADARG_ATOM);
203+
}
204+
struct JITStreamMMap *js_obj = (struct JITStreamMMap *) js_obj_ptr;
205+
if (IS_NULL_PTR(js_obj->stream_base)) {
206+
RAISE_ERROR(BADARG_ATOM);
207+
}
208+
209+
#if defined(__APPLE__)
210+
sys_icache_invalidate(js_obj->stream_base, js_obj->stream_size);
211+
#elif defined(__GNUC__)
212+
__builtin___clear_cache(js_obj->stream_base, js_obj->stream_base + js_obj->stream_size);
213+
#endif
214+
215+
return argv[0];
216+
}
217+
196218
static term nif_jit_stream_module(Context *ctx, int argc, term argv[])
197219
{
198220
UNUSED(argc);
@@ -226,6 +248,10 @@ static const struct Nif jit_stream_mmap_read_nif = {
226248
.base.type = NIFFunctionType,
227249
.nif_ptr = nif_jit_stream_mmap_read
228250
};
251+
static const struct Nif jit_stream_mmap_flush_nif = {
252+
.base.type = NIFFunctionType,
253+
.nif_ptr = nif_jit_stream_mmap_flush
254+
};
229255

230256
ModuleNativeEntryPoint jit_stream_entry_point(Context *ctx, term jit_stream)
231257
{
@@ -239,18 +265,14 @@ ModuleNativeEntryPoint jit_stream_entry_point(Context *ctx, term jit_stream)
239265
return NULL;
240266
}
241267

242-
#if defined(__APPLE__)
243-
sys_icache_invalidate(js_obj->stream_base, js_obj->stream_size);
244-
#elif defined(__GNUC__)
245-
__builtin___clear_cache(js_obj->stream_base, js_obj->stream_base + js_obj->stream_size);
246-
#endif
247268
#if JIT_ARCH_TARGET == JIT_ARCH_ARMV6M
248269
// Set thumb bit for armv6m
249270
ModuleNativeEntryPoint result = (ModuleNativeEntryPoint) js_obj->stream_base + 1;
250271
#else
251272
ModuleNativeEntryPoint result = (ModuleNativeEntryPoint) js_obj->stream_base;
252273
#endif
253274

275+
// Prevent module from being unmapped by dtor
254276
js_obj->stream_base = NULL;
255277
return result;
256278
}
@@ -291,6 +313,9 @@ const struct Nif *jit_stream_mmap_get_nif(const char *nifname)
291313
if (strcmp("read/3", rest) == 0) {
292314
return &jit_stream_mmap_read_nif;
293315
}
316+
if (strcmp("flush/1", rest) == 0) {
317+
return &jit_stream_mmap_flush_nif;
318+
}
294319
}
295320
return NULL;
296321
}

0 commit comments

Comments
 (0)