Age | Commit message (Collapse) | Author |
|
* maint:
dialyzer: Fix a bug affecting keyfind/keysearch/keymember
|
|
|
|
* maint:
Updated OTP version
Prepare release
|
|
|
|
hipe: Cleanup and fix specs of the hipe module
|
|
hipe_llvm_main: fix tmpfs dir on FreeBSD
|
|
HiPE: Fix check for when ErLLVM is available
|
|
There was a lot of confusion between file vs. module names in the
function specification of the hipe module (as also discovered by #1992)
and this PR cleans up and fixes them.
|
|
* maint:
beam_lib: Remove obsolete module() from the beam() type
hipe: Don't use beam_lib:info/1 with an atom as filename
Honor the max heap size when copying literals after purging
|
|
|
|
The previous check whether ErLLVM could be enabled and/or tested simply
checked whether a suitable version of the LLVM tool chain was present
in the path. Obviously this is not enough: there should also be a check
that we are running in an architecture on which the ErLLVM compiler
has been ported. Fix the function that provides this functionality and
also rename it in order to more appropriately describe what it does.
In principle, this change introduces a backwards incompatibility as the
function is one of those exported by the `hipe' module, but this
function was not documented and the chances that it has been used
somewhere else that the test suite are pretty low (if not zero).
|
|
Rewrite BSM optimizations in the new SSA-based intermediate format
|
|
|
|
|
|
Upstream this patch from FreeBSD Ports:
https://svnweb.freebsd.org/ports/head/lang/erlang-runtime21/files/patch-lib_hipe_llvm_hipe__llvm__main.erl?revision=473434&view=markup
|
|
|
|
|
|
|
|
|
|
Sometimes when building a tuple, there is no way to avoid an
extra `move` instruction. Consider this code:
make_tuple(A) -> {ok,A}.
The corresponding BEAM code looks like this:
{test_heap,3,1}.
{put_tuple,2,{x,1}}.
{put,{atom,ok}}.
{put,{x,0}}.
{move,{x,1},{x,0}}.
return.
To avoid overwriting the source register `{x,0}`, a `move`
instruction is necessary.
The problem doesn't exist when building a list:
%% build_list(A) -> [A].
{test_heap,2,1}.
{put_list,{x,0},nil,{x,0}}.
return.
Introduce a new `put_tuple2` instruction that builds a tuple in a
single instruction, so that the `move` instruction can be eliminated:
%% make_tuple(A) -> {ok,A}.
{test_heap,3,1}.
{put_tuple2,{x,0},{list,[{atom,ok},{x,0}]}}.
return.
Note that the BEAM loader already combines `put_tuple` and `put`
instructions into an internal instruction similar to `put_tuple2`.
Therefore the introduction of the new instruction will not speed up
execution of tuple building itself, but it will be less work for
the loader to load the new instruction.
|
|
If one of the destination registers for get_map_elements is
the same as the map source, extract that element last.
|
|
I did not find any legitimate use of "can not", however skipped
changing e.g RFCs archived in the source tree.
|
|
After this whitespace modification there should be no "can not"s
separated by a newline in the entire OTP repository, so to find
them all a simple git grep will do just fine.
|
|
|
|
|
|
|
|
Fix a crash in HiPE's lazy code motion pass
|
|
* rickard/hipe-doc:
Update information about HiPE
|
|
|
|
Some change in the BEAM compiler resulted in the creation of basic
blocks that differed from those previously created by the compiler.
As a result, the lazy code motion pass of RTL crashed when compiling
some of the new code.
Crashes were privately reported by @richcarl.
|
|
|
|
This reverts commit fd8e49b5bddceaae803670121b603b5eee8c5c08.
|
|
|
|
|
|
* richcarl/eliminate_lib_module/PR-1786/OTP-15072:
Fix minor issues
Eliminate call to ct:get_progname() in ts_erl_config
Use \n escape instead of integer 10
Move error formatting to erl_error.erl and delete lib.erl
Move extended parse functions in lib.erl to erl_eval.erl
Move lib:eval_str/1 into mod_esi.erl
Remove lib:progname/0
Eliminate call to lib:progname/1 in slave.erl
Add ct:get_progname/0
Remove lib:error_message/2
Remove lib:flush_receive/0
Remove lib:send/2 and lib:sendw/2
Move lib:nonl/1 into yecc.erl
|
|
Introduce is_map_key/2 guard BIF
OTP-15037
|
|
Three of the removed source files don't even compile.
Uncompilable source files cause problems for tools such as
scripts/diffable that want to compile all found source files.
|
|
|
|
This complements the `map_get/2` guard BIF introduced in #1784.
Rationale.
`map_get/2` allows accessing map fields in guards, but it might be
problematic in more complex guard expressions, for example:
foo(X) when map_get(a, X) =:= 1 or is_list(X) -> ...
The `is_list/1` part of the guard could never succeed since the
`map_get/2` guard would fail the whole guard expression. In this
situation, this could be solved by using `;` instead of `or` to separate
the guards, but it is not possible in every case.
To solve this situation, this PR proposes a `is_map_key/2` guard that
allows to check if a map has key inside a guard before trying to access
that key. When combined with `is_map/1` this allows to construct a
purely boolean guard expression testing a value of a key in a map.
Implementation.
Given the use case motivating the introduction of this function, the PR
contains compiler optimisations that produce optimial code for the
following guard expression:
foo(X) when is_map(X) and is_map_key(a, X) and map_get(a, X) =:= 1 -> ok;
foo(_) -> error.
Given all three tests share the failure label, the `is_map_key/2` and
`is_map/2` tests are optimised away.
As with `map_get/2` the `is_map_key/2` BIF is allowed in match specs.
|
|
The existing test/0 function in erl_types was not being run in the OTP test
suite, and it had not been updated to match the implementation in the
module (maps vs. dict). This commit removes the macros that excluded some
functions, exports the functions now included in the module, and extracts the
test into a new common_test suite, erl_types_SUITE.
|
|
* 'map-get-bif' of git://github.com/michalmuskala/otp:
Introduce map_get guard-safe function
OTP-15037
|
|
Rationale
Today all compound data types except for maps can be deconstructed in guards.
For tuples we have `element/2` and for lists `hd/1` and `tl/1`. Maps are
completely opaque to guards. This means matching on maps can't be
abstracted into macros, which is often done with repetitive guards. It
also means that maps have to be always selected whole from ETS tables,
even when only one field would be enough, which creates a potential
efficiency issue.
This PR introduces an `erlang:map_get/2` guard-safe function that allows
extracting a map field in guard. An alternative to this function would be
to introduce the syntax for extracting a value from a map that was planned
in the original EEP: `Map#{Key}`.
Even outside of guards, since this function is a guard-BIF it is more
efficient than using `maps:get/2` (since it does not need to set up the
stack), and more convenient from pattern matching on the map (compare:
`#{key := Value} = Map, Value` to `map_get(key, Map)`).
Performance considerations
A common concern against adding this function is the notion that "guards
have to be fast" and ideally execute in constant time. While there are
some counterexamples (`length/1`), what is more important is the fact
that adding those functions does not change in any way the time
complexity of pattern matching - it's already possible to match on map
fields today directly in patterns - adding this ability to guards will
niether slow down or speed up the execution, it will only make certain
programs more convenient to write.
This first version is very naive and does not perform any optimizations.
|
|
|
|
Implementation of true asynchronous signaling between processes
|
|
Communication between Erlang processes has conceptually always been
performed through asynchronous signaling. The runtime system
implementation has however previously preformed most operation
synchronously. In a system with only one true thread of execution, this
is not problematic (often the opposite). In a system with multiple threads
of execution (as current runtime system implementation with SMP support)
it becomes problematic. This since it often involves locking of structures
when updating them which in turn cause resource contention. Utilizing
true asynchronous communication often avoids these resource contention
issues.
The case that triggered this change was contention on the link lock due
to frequent updates of the monitor trees during communication with a
frequently used server. The signal order delivery guarantees of the
language makes it hard to change the implementation of only some signals
to use true asynchronous signaling. Therefore the implementations
of (almost) all signals have been changed.
Currently the following signals have been implemented as true
asynchronous signals:
- Message signals
- Exit signals
- Monitor signals
- Demonitor signals
- Monitor triggered signals (DOWN, CHANGE, etc)
- Link signals
- Unlink signals
- Group leader signals
All of the above already defined as asynchronous signals in the
language. The implementation of messages signals was quite
asynchronous to begin with, but had quite strict delivery constraints
due to the ordering guarantees of signals between a pair of processes.
The previously used message queue partitioned into two halves has been
replaced by a more general signal queue partitioned into three parts
that service all kinds of signals. More details regarding the signal
queue can be found in comments in the erl_proc_sig_queue.h file.
The monitor and link implementations have also been completely replaced
in order to fit the new asynchronous signaling implementation as good
as possible. More details regarding the new monitor and link
implementations can be found in the erl_monitor_link.h file.
|
|
Remove unused cerl_messagean module
|
|
Conflicts:
OTP_VERSION
|
|
|
|
|
|
|