Age | Commit message (Collapse) | Author |
|
Use the md5 of the native code chunk instead of the Beam code md5.
|
|
The hipe_bifs:make_native_stub/2 and hipe_bifs:get_emu_address/1
BIFs were originally used by hipe_unified_loader.erl, but the
code been obsolete and disabled for ages.
Remove the BIFs and all references to them.
In hipe_unified_loader.erl, remove the no-op emu_make_stubs/1
function.
|
|
Add flags to enable and use the LLVM backend:
* to_llvm: use the LLVM pipeline for compilation (default optimization level
is O3),
* llvm_save_temps: save the intermediate files in current directory in order
to be able to debug or optimize the LLVM assembly,
* {to_llvm, O}: set the optimization level of LLVM opt and llc tools.
Add some debug support to the loader; no semantic change intented.
|
|
The loader of native code tries to avoid race condition by bringing
down the system to a single scheduler. Unfortunately, that will not
completely avoid race conditions beacuse other processes may still
run while the code is being loaded. Therefore, we must still make
sure that native code has been fully fixed up before it can be
executed.
Under unlucky circumstances, it was possible for the global name
register process to call a fun in native code before the native
code for the fun had been fully fixed up. The run-time system
would crash when running the not-fully-fixed-up code.
Here is a way to make the bug 100% reproducible. First add this
function to the 'global' module:
silly_looper(List) ->
lists:foreach(fun(E) -> put(any_atom, E) end, List),
silly_looper(List).
Then insert the following code at the beginning of the init/1
function in the 'global' module:
spawn_link(fun() -> silly_looper(lists:seq(1, 100)) end),
The run-time system will crash during start up when the native
code for the 'global' module is being loaded. What will happen
is that lists:foreach/2 (which runs in native code) will call
the native code for the fun in silly_looper/1 before the reference
to 'any_atom' has been changed from a 0 to the proper tagged
atom value. The put/2 BIF will exit when attempting to calculate
the hash value for the illegal value 0 (it is not properly tagged).
To eliminate this race condition, we must delay patching the
native code addresses for a fun into the fun entry until the native
code has been fully fixed up. We will use the new BIFs introduced
in the previous commit.
While we are at it, we will also make sure that we erase any
temporary variables in the process dictionary used by the
hipe_unified_loader module.
|
|
This commit is a preparation for eliminating a race condition
loading the native code for modules whose BEAM code has already
been loaded. Here we introduce two new BIFs so that looking up
a fun entry is separate from setting the native address in the
fun entry.
|
|
Conflicts:
bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
|
|
Consisting of three items:
- Eliminate uses of is_subtype/2 in specs
- Change module-local void functions to return 'ok' instead of []
- Make sure there are no dialyzer warnings with --Wunmatched_returns
|
|
|
|
In order to avoid an ummatched return warning in erts and make the code
more sane, the return value of the bif was changed from [] to 'ok'.
(Probably more hipe_bifs need such changes but they will have to wait.)
While at it, the code of various functions in hipe_unified_loader was
shortened by using lists:foreach/1 instead of explicit recursion.
|
|
Workaround for crash in code_server.
|
|
|
|
Strange that the effect of this bug is not more fatal.
Kudos to Fabian and Tom for spotting this one.
|
|
We want to be able to write type specifications for BIFs in the same
way as for any other function. Currently, the type for BIFs need
to be described in erl_bif_types.
To avoid extending the compiler and Dialyzer with special directives
for providing specifications for BIFs, we have decided to let the
loader accept a local definition for a function which exists as a
BIF. As an example, here is how a stub for lists:reverse/2 can be
defined:
-export([reverse/2]).
-spec reverse([term()], term()) -> [term()].
reverse(_, _) ->
erlang:nif_error(undef).
Essentially, the loader will discard the local definition of reverse/2.
Other functions in the same module must *not* do local calls to a BIF
stub. If a local call to a BIF is found, the loader will refuse to load
the module. That is, the following call is not allowed:
reverse(List) ->
reverse(List, []).
but the following is:
reverse(List) ->
?MODULE:reverse(List, []).
A few words about the implementation.
It turns out to be too complicated to actually discard the BIF
stubs. Although it would be possibly with some jiggery pokery in
ops.tab, the code would be difficult to maintain and it could slow
down loading of modules that don't define BIFs (which are almost
all modules).
Therefore, the stub functions are kept in the loaded code, but
their names in the func_info instruction are invalidated so that
module_info(functions) can filter them out.
|
|
Reorganize in a systematic way the code that loads the modules needed
by the code_server process. While at it, remove the useless
hipe_unified_loader:load_hipe_modules/0 function.
|
|
|
|
This avoids costly scheduling changes during module loading if native
code is disabled in erts, or not present in the module being loaded.
Signed-off-by: Mikael Pettersson <[email protected]>
|
|
Loading native code is a multi-step operation that needs to be
atomic, but the HiPE loader failed to ensure that.
This caused corruption of runtime system structure in some cases.
Fix by blocking multi_scheduling around main loader entry points.
Signed-off-by: Mikael Pettersson <[email protected]>
|
|
|