diff options
author | Björn Gustavsson <[email protected]> | 2015-04-28 08:49:08 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-05-06 10:19:06 +0200 |
commit | 7309ff4c3832588cc15565ff264db2a120e6092e (patch) | |
tree | f519a02ddab40368972681882c12e272ab05f2aa /lib/kernel | |
parent | 8adbf1a5407dbb8b64070bddbea0bb364e759dd0 (diff) | |
download | otp-7309ff4c3832588cc15565ff264db2a120e6092e.tar.gz otp-7309ff4c3832588cc15565ff264db2a120e6092e.tar.bz2 otp-7309ff4c3832588cc15565ff264db2a120e6092e.zip |
code: Reduce overhead of native code checking for loaded modules
When the code server has been started, the function
load_native_code_for_all_loaded/0 will check whether the .beam
files for all loaded modules contain any native code. If there
is native code, it will be loaded.
If there is no native code, on my computer the check will take about
10 ms. That time can be reduced to about 2 ms if we replace the call
to code beam_lib:chunks/2 with a call to prim_file:read_file/1 to read
the file and a call to code:get_chunk/2 to check whether the chunk for
native code is present.
Furthermore, the entire check can be spawned off to a separate
process and done in parallel with OTP starting up.
Diffstat (limited to 'lib/kernel')
-rw-r--r-- | lib/kernel/src/code.erl | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index 0eda558ed5..a8cbdf9667 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -339,7 +339,7 @@ do_start(Flags) -> ok end, %% Quietly load native code for all modules loaded so far - catch load_native_code_for_all_loaded(), + load_native_code_for_all_loaded(), Ok2; Other -> Other @@ -550,18 +550,41 @@ has_ext(Ext, Extlen, File) -> _ -> false end. +%%% +%%% Silently load native code for all modules loaded so far. +%%% + -spec load_native_code_for_all_loaded() -> ok. load_native_code_for_all_loaded() -> Architecture = erlang:system_info(hipe_architecture), - ChunkName = hipe_unified_loader:chunk_name(Architecture), - lists:foreach(fun({Module, BeamFilename}) -> - case code:is_module_native(Module) of - false -> - case beam_lib:chunks(BeamFilename, [ChunkName]) of - {ok,{_,[{_,Bin}]}} when is_binary(Bin) -> - load_native_partial(Module, Bin); - {error, beam_lib, _} -> ok - end; - true -> ok - end - end, all_loaded()). + try hipe_unified_loader:chunk_name(Architecture) of + ChunkTag -> + Loaded = all_loaded(), + spawn(fun() -> load_all_native(Loaded, ChunkTag) end) + catch + _:_ -> + ok + end. + +load_all_native(Loaded, ChunkTag) -> + catch load_all_native_1(Loaded, ChunkTag). + +load_all_native_1([{_,preloaded}|T], ChunkTag) -> + load_all_native_1(T, ChunkTag); +load_all_native_1([{Mod,BeamFilename}|T], ChunkTag) -> + case code:is_module_native(Mod) of + false -> + %% prim_file is faster than file and the file server may + %% not be started yet. + {ok,Beam} = prim_file:read_file(BeamFilename), + case code:get_chunk(Beam, ChunkTag) of + undefined -> + ok; + NativeCode when is_binary(NativeCode) -> + load_native_partial(Mod, NativeCode) + end; + true -> ok + end, + load_all_native_1(T, ChunkTag); +load_all_native_1([], _) -> + ok. |