Age | Commit message (Collapse) | Author |
|
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.
|
|
If no message/signal is sent (to same destination)
then monitor signal is flushed when process is scheduled out.
|
|
|
|
* rickard/dirty-schedulers-test-fix/OTP-15046:
Do not run tests that conflicts with dirty schedulers test
|
|
* siri/upgrade_SUITE/stop-inets-before-start-ftp:
Add correction of relup when upgrading from 20-21 with inets and ftp/tftp
|
|
* rickard/process_info/OTP-14966:
Restore merge of signal queues in queue_messages() if main lock is held
Fix message tracing
|
|
Remove config test of MAP_NORESERVE for hipe on x86_64
|
|
|
|
|
|
* hasse/stdlib/map_guards_shell/OTP-15035/ERL-613:
erts: Correct abstract format doc regarding map creation
stdlib: Correct the linter's check of map guard expressions
|
|
|
|
* 'map-get-bif' of git://github.com/michalmuskala/otp:
Introduce map_get guard-safe function
OTP-15037
|
|
* lukas/erts/poll-thread/OTP-14346:
erts: nif resource stop from poll-thread is a indirect call
|
|
* lukas/erts/dump_SUITE_fix:
erts: Increase file read timeout for signal_abort test
|
|
* john/erts/fix-lcnt-toggle-test:
Disregard locks that can't be toggled in lcnt_SUITE
|
|
Improve memory instrumentation
OTP-15024
OTP-14961
|
|
|
|
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.
|
|
fix integer truncation bugs in error logger path
|
|
|
|
* sverker/valgrind-uninit-run_queue-ptr:
erts: Fix run queue pointer in proxy process
|
|
* sverker/ets-cherries/OTP-15031:
erts: Use table ref for select continuation
erts: Refactor erl_db_hash next() into next_live()
erts: Change wrong alloc_fnf
|
|
This commit replaces the old memory instrumentation with a new
implementation that scans carriers instead of wrapping
erts_alloc/erts_free. The old implementation could not extract
information without halting the emulator, had considerable runtime
overhead, and the memory maps it produced were noisy and lacked
critical information.
Since the new implementation walks through existing data structures
there's no longer a need to start the emulator with special flags to
get information about carrier utilization/fragmentation. Memory
fragmentation is also easier to diagnose as it's presented on a
per-carrier basis which eliminates the need to account for "holes"
between mmap segments.
To help track allocations, each allocation can now be tagged with
what it is and who allocated it at the cost of one extra word per
allocation. This is controlled on a per-allocator basis with the
+M<S>atags option, and is enabled by default for binary_alloc and
driver_alloc (which is also used by NIFs).
|
|
|
|
|
|
* lukas/erts/seq_tracer_nif/OTP-15029:
Fix seq_trace erl_tracer bug
Fix makefile mkdir warning
|
|
* john/erts/fix-sbwt-links:
Fix seealso tags for +sbwt/+swt
|
|
Sending a large term to the error logger has two problems related
to the size and sign of the variables used to represent lengths:
- the API functions (erts_send_error_term_to_logger() et al) perform
an unchecked narrowing conversion from size_t to int when passing
dsbufp->str_len to the internal functions; this may both truncate
the length and make it negative
- do_send_term_to_logger() and do_send_to_logger() multiply the
int-typed length by 2 before widening it to Uint and adding a few
more values; the intermediate product may overflow causing loss
of high bits and a change of sign; if the intermediate product is
negative the final size will be an extremely large positive value
The end result is that the computed buffer size can be arbitrarily
wrong, either too small or too large.
While reviewing this code I also found and fixed a potential narrowing
bug in erts_set_hole_marker().
|
|
and not the name. For more sane named table semantics.
Applies to both select/1 continuation and trap context.
|
|
where argument 'list' is the first candidate (not list->next).
Also simplified db_first_hash().
|
|
There is no NULL check here !?
|
|
and instead test for mprotect which is what is uses.
The use of MAP_NORESERVE for hipe code allocations
was removed in 8fd6e3353b094aa94e37e257ee20cd5e0e5dddcb.
|
|
Optimize performance of float_to_list/2
|
|
|
|
proc->run_queue detected as uninitialized by valgrind
but seems harmless in practice as it's not used for proxy processes.
"Bug" introduced in OTP-17 by ca0425c6ff85262bc15367f5fd9cbc51cde52b20
and made worse (but still harmless) in master for OTP-21
at fbb10ebc4a37555c7ea7f99e14286d862993976a.
|
|
Deprecate erlang:get_stacktrace/1
|
|
|
|
Make stacktraces consistent when backtrace_depth is 0
|
|
into aclocal.m4 as LM_HARDWARE_ARCH
|
|
|
|
It is allowed to set the backtrace depth to 0, but when
an exception is catched the stacktrace will still contain
one element:
1> erlang:system_flag(backtrace_depth, 0).
8
2> catch error(badarg).
{'EXIT',{badarg,[{shell,apply_fun,3,
[{file,"shell.erl"},{line,908}]}]}}
However, when an exception is raised using `erlang:raise/3`, there
will be no elements in the stacktrace:
3> catch erlang:raise(error, badarg, [{fake,name,[arg],[]}]).
{'EXIT',{badarg,[]}}
Since the `error_handler` module uses `erlang:raise/3` to
raise an exception when an undefined function is called,
there will not be any stacktrace when calling an undefined
function:
4> catch undef_module:undef_name(some_argument).
{'EXIT',{undef,[]}}
Fix this inconsistency by changing `erlang:raise/3` so that
it always includes one element in the stacktrace:
3> catch erlang:raise(error, badarg, [{fake,name,[arg],[]}]).
{'EXIT',{badarg,[{fake,name,[arg],[]}]}}
4> catch undef_module:undef_name(some_argument).
{'EXIT',{undef,[{undef_module,undef_name,[some_argument],[]}]}}
|
|
christhekeele/remove-trace-terms-from-table-types-in-match-docs
Remove trace-specific terms from docs for table-oriented matchspecs
|
|
This removes the matchspec instructions `is_seq_trace` and `get_tcw/0`
from the documentation for table-oriented matchspecs.
This is likely correct as both are already documented under "Functions
Allowed Only for Tracing", despite appearing in the list of possible
options for table specs.
The following observations further back this change up:
```erl
erlang:match_spec_test([whatever], [{'_', [], [{is_seq_trace}]}], trace).
%=> {ok,true,[],[]}
erlang:match_spec_test({whatever}, [{'_', [], [{is_seq_trace}]}], table).
%=> {error,[{error,"Special form 'is_seq_trace' used in wrong %dialect."}]}
erlang:match_spec_test([whatever], [{'_', [], [{get_tcw}]}], trace).
%=> {ok,true,[],[]}
erlang:match_spec_test({whatever}, [{'_', [], [{get_tcw}]}], table).
%=> {error,[{error,"Function get_tcw/0 cannot be called in this context."}]}
```
|
|
|
|
OTP-15024
|
|
|
|
This may be of interest in crash dumps and allows the upcoming
allocation tagging feature to track allocations on a per-NIF basis.
Note that this is only updated when user code calls a NIF; it's not
altered when the emulator calls NIFs during code upgrades or
tracing.
|
|
|
|
This increases the accuracy of crash dumps and the upcoming
allocation tagging feature.
|
|
|